Override 'all' method of a model in Ruby on Rails
up vote
-1
down vote
favorite
I have an Account
model that has columns:
id :bigint(8)
name :string
In app/models/account.rb
, I have:
class Account < ApplicationRecord
has_one_attached :logo
end
This is an API, and the controller only returns JSON. In my controller, I have:
render :json => Account.all
The code above returns:
[
"id": 1,
"name": "Example1"
,
"id": 2,
"name": "Example2"
]
I want to also include the url of the ActiveStorage
file attached to the JSON returned.
In order to achieve that, I am doing this in the controller:
def index
@accounts =
Account.all.map do |account|
account =
account.attributes.merge(
:logo_url =>
account.logo.attached? ?
polymorphic_url(account.logo) : nil
)
end
render :json => @accounts
end
This will return:
[
"id": 1,
"name": "Example1",
"logo_url": "/path/to/logo.jpg"
,
"id": 2,
"name": "Example2",
"logo_url": "/path/to/logo.jpg"
]
However, I don't want to do this whenever I call Account.all
; I want to automatically add the logo_url
whenever Account.all
is called.
I have come up with this solution; instead of calling it in the controller, I decided to override the method in the model. In app/models/account.rb
, I added:
def self.all
super.map do |account|
account =
account.attributes.merge(
:logo_url =>
account.logo.attached? ?
polymorphic_url(account.logo) : nil
)
end
end
The code above works so well. The problem is that methods find
, find_by
, where
, and other methods stopped working. And if I remove the self.all
method from account.rb
, it works again.
The following codes:
Account.find_by :id => params[:id]
Account.find params[:id]
raise an error:
undefined method `where' for #<Array:0x00007fd09b68d670>
I believe this happens because self.all
returns an array instead of an active record.
How can I override the all
method in the model?
ruby-on-rails
add a comment |
up vote
-1
down vote
favorite
I have an Account
model that has columns:
id :bigint(8)
name :string
In app/models/account.rb
, I have:
class Account < ApplicationRecord
has_one_attached :logo
end
This is an API, and the controller only returns JSON. In my controller, I have:
render :json => Account.all
The code above returns:
[
"id": 1,
"name": "Example1"
,
"id": 2,
"name": "Example2"
]
I want to also include the url of the ActiveStorage
file attached to the JSON returned.
In order to achieve that, I am doing this in the controller:
def index
@accounts =
Account.all.map do |account|
account =
account.attributes.merge(
:logo_url =>
account.logo.attached? ?
polymorphic_url(account.logo) : nil
)
end
render :json => @accounts
end
This will return:
[
"id": 1,
"name": "Example1",
"logo_url": "/path/to/logo.jpg"
,
"id": 2,
"name": "Example2",
"logo_url": "/path/to/logo.jpg"
]
However, I don't want to do this whenever I call Account.all
; I want to automatically add the logo_url
whenever Account.all
is called.
I have come up with this solution; instead of calling it in the controller, I decided to override the method in the model. In app/models/account.rb
, I added:
def self.all
super.map do |account|
account =
account.attributes.merge(
:logo_url =>
account.logo.attached? ?
polymorphic_url(account.logo) : nil
)
end
end
The code above works so well. The problem is that methods find
, find_by
, where
, and other methods stopped working. And if I remove the self.all
method from account.rb
, it works again.
The following codes:
Account.find_by :id => params[:id]
Account.find params[:id]
raise an error:
undefined method `where' for #<Array:0x00007fd09b68d670>
I believe this happens because self.all
returns an array instead of an active record.
How can I override the all
method in the model?
ruby-on-rails
add a comment |
up vote
-1
down vote
favorite
up vote
-1
down vote
favorite
I have an Account
model that has columns:
id :bigint(8)
name :string
In app/models/account.rb
, I have:
class Account < ApplicationRecord
has_one_attached :logo
end
This is an API, and the controller only returns JSON. In my controller, I have:
render :json => Account.all
The code above returns:
[
"id": 1,
"name": "Example1"
,
"id": 2,
"name": "Example2"
]
I want to also include the url of the ActiveStorage
file attached to the JSON returned.
In order to achieve that, I am doing this in the controller:
def index
@accounts =
Account.all.map do |account|
account =
account.attributes.merge(
:logo_url =>
account.logo.attached? ?
polymorphic_url(account.logo) : nil
)
end
render :json => @accounts
end
This will return:
[
"id": 1,
"name": "Example1",
"logo_url": "/path/to/logo.jpg"
,
"id": 2,
"name": "Example2",
"logo_url": "/path/to/logo.jpg"
]
However, I don't want to do this whenever I call Account.all
; I want to automatically add the logo_url
whenever Account.all
is called.
I have come up with this solution; instead of calling it in the controller, I decided to override the method in the model. In app/models/account.rb
, I added:
def self.all
super.map do |account|
account =
account.attributes.merge(
:logo_url =>
account.logo.attached? ?
polymorphic_url(account.logo) : nil
)
end
end
The code above works so well. The problem is that methods find
, find_by
, where
, and other methods stopped working. And if I remove the self.all
method from account.rb
, it works again.
The following codes:
Account.find_by :id => params[:id]
Account.find params[:id]
raise an error:
undefined method `where' for #<Array:0x00007fd09b68d670>
I believe this happens because self.all
returns an array instead of an active record.
How can I override the all
method in the model?
ruby-on-rails
I have an Account
model that has columns:
id :bigint(8)
name :string
In app/models/account.rb
, I have:
class Account < ApplicationRecord
has_one_attached :logo
end
This is an API, and the controller only returns JSON. In my controller, I have:
render :json => Account.all
The code above returns:
[
"id": 1,
"name": "Example1"
,
"id": 2,
"name": "Example2"
]
I want to also include the url of the ActiveStorage
file attached to the JSON returned.
In order to achieve that, I am doing this in the controller:
def index
@accounts =
Account.all.map do |account|
account =
account.attributes.merge(
:logo_url =>
account.logo.attached? ?
polymorphic_url(account.logo) : nil
)
end
render :json => @accounts
end
This will return:
[
"id": 1,
"name": "Example1",
"logo_url": "/path/to/logo.jpg"
,
"id": 2,
"name": "Example2",
"logo_url": "/path/to/logo.jpg"
]
However, I don't want to do this whenever I call Account.all
; I want to automatically add the logo_url
whenever Account.all
is called.
I have come up with this solution; instead of calling it in the controller, I decided to override the method in the model. In app/models/account.rb
, I added:
def self.all
super.map do |account|
account =
account.attributes.merge(
:logo_url =>
account.logo.attached? ?
polymorphic_url(account.logo) : nil
)
end
end
The code above works so well. The problem is that methods find
, find_by
, where
, and other methods stopped working. And if I remove the self.all
method from account.rb
, it works again.
The following codes:
Account.find_by :id => params[:id]
Account.find params[:id]
raise an error:
undefined method `where' for #<Array:0x00007fd09b68d670>
I believe this happens because self.all
returns an array instead of an active record.
How can I override the all
method in the model?
ruby-on-rails
ruby-on-rails
edited Nov 9 at 9:00
sawa
128k27193298
128k27193298
asked Nov 9 at 2:43
David Angulo
610320
610320
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
I don't think you want to override Account.all
.
Instead you want to change the default serialization of your model.
Try this:
class Account < ApplicationRecord
has_one_attached :logo
private
def serializable_hash(options)
super(options).merge("logo_url" => logo_url)
end
def logo_url
logo.attached? ? polymorphic_url(account.logo) : nil
end
end
The controller ends up calling to_json
on your model and the will end up using the #serializable_hash
. Since to_son
takes options to set a root of the json, it's best to override serializable_hash
. Another approach is to create a separate serializer classes per model but this should be suitable for a simple case.
Can you show how to implement it in the controller?
– David Angulo
Nov 9 at 5:14
I believe it will work in the controller because the controller will try to serialize the models and callto_json
on them which will invoke the new code.
– Derek
Nov 9 at 15:37
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
I don't think you want to override Account.all
.
Instead you want to change the default serialization of your model.
Try this:
class Account < ApplicationRecord
has_one_attached :logo
private
def serializable_hash(options)
super(options).merge("logo_url" => logo_url)
end
def logo_url
logo.attached? ? polymorphic_url(account.logo) : nil
end
end
The controller ends up calling to_json
on your model and the will end up using the #serializable_hash
. Since to_son
takes options to set a root of the json, it's best to override serializable_hash
. Another approach is to create a separate serializer classes per model but this should be suitable for a simple case.
Can you show how to implement it in the controller?
– David Angulo
Nov 9 at 5:14
I believe it will work in the controller because the controller will try to serialize the models and callto_json
on them which will invoke the new code.
– Derek
Nov 9 at 15:37
add a comment |
up vote
1
down vote
accepted
I don't think you want to override Account.all
.
Instead you want to change the default serialization of your model.
Try this:
class Account < ApplicationRecord
has_one_attached :logo
private
def serializable_hash(options)
super(options).merge("logo_url" => logo_url)
end
def logo_url
logo.attached? ? polymorphic_url(account.logo) : nil
end
end
The controller ends up calling to_json
on your model and the will end up using the #serializable_hash
. Since to_son
takes options to set a root of the json, it's best to override serializable_hash
. Another approach is to create a separate serializer classes per model but this should be suitable for a simple case.
Can you show how to implement it in the controller?
– David Angulo
Nov 9 at 5:14
I believe it will work in the controller because the controller will try to serialize the models and callto_json
on them which will invoke the new code.
– Derek
Nov 9 at 15:37
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
I don't think you want to override Account.all
.
Instead you want to change the default serialization of your model.
Try this:
class Account < ApplicationRecord
has_one_attached :logo
private
def serializable_hash(options)
super(options).merge("logo_url" => logo_url)
end
def logo_url
logo.attached? ? polymorphic_url(account.logo) : nil
end
end
The controller ends up calling to_json
on your model and the will end up using the #serializable_hash
. Since to_son
takes options to set a root of the json, it's best to override serializable_hash
. Another approach is to create a separate serializer classes per model but this should be suitable for a simple case.
I don't think you want to override Account.all
.
Instead you want to change the default serialization of your model.
Try this:
class Account < ApplicationRecord
has_one_attached :logo
private
def serializable_hash(options)
super(options).merge("logo_url" => logo_url)
end
def logo_url
logo.attached? ? polymorphic_url(account.logo) : nil
end
end
The controller ends up calling to_json
on your model and the will end up using the #serializable_hash
. Since to_son
takes options to set a root of the json, it's best to override serializable_hash
. Another approach is to create a separate serializer classes per model but this should be suitable for a simple case.
answered Nov 9 at 4:11
Derek
926710
926710
Can you show how to implement it in the controller?
– David Angulo
Nov 9 at 5:14
I believe it will work in the controller because the controller will try to serialize the models and callto_json
on them which will invoke the new code.
– Derek
Nov 9 at 15:37
add a comment |
Can you show how to implement it in the controller?
– David Angulo
Nov 9 at 5:14
I believe it will work in the controller because the controller will try to serialize the models and callto_json
on them which will invoke the new code.
– Derek
Nov 9 at 15:37
Can you show how to implement it in the controller?
– David Angulo
Nov 9 at 5:14
Can you show how to implement it in the controller?
– David Angulo
Nov 9 at 5:14
I believe it will work in the controller because the controller will try to serialize the models and call
to_json
on them which will invoke the new code.– Derek
Nov 9 at 15:37
I believe it will work in the controller because the controller will try to serialize the models and call
to_json
on them which will invoke the new code.– Derek
Nov 9 at 15:37
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53219117%2foverride-all-method-of-a-model-in-ruby-on-rails%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown