Reputation: 151
I have tableless model (like it was shown in #219 railscast):
class MyModel
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :attr1, :attr2, :attr3, :attr4
private
def initialize(attr1 = nil)
self.attr1 = attr1
end
def persisted?
false
end
end
Then I'm trying to render JSON in controller:
@my_model = MyModel.new
render json: @my_model.to_json(only: [:attr1, :attr2])
but it renders JSON with all the attributes of the model.
I've tried to add
include ActiveModel::Serialization
but it didn't change rendered JSON.
How can I render JSON with only necessary attributes of my tableless model?
I'm using Rails 3.2.3
Update
Thanks, guys. It seems you're all almost right. I combined your solutions and got this:
Model:
include ActiveModel::Serialization
...
def to_hash
{
attr1: self.attr1,
attr2: self.attr2,
...
}
end
Controller:
render json: @my_model.to_hash.to_json(only: [:attr1, :attr2])
I really don't know whose answer to be accepted.
Update 2
Suddenly new strangeness appeared. One of the attributes is array of hashes. It was like this:
attr1: [[{name: "name", image: "image"}, {name: "name", image: "image"}],
[{name: "name", image: "image"}, {name: "name", image: "image"}]]
But now it lost all its content and looks like this:
attr1: [[{}, {}], [{}, {}]]
Maybe anyone know how to fix it?
Update 3 :)
Erez Rabih's answer helped. Using slice
instead of to_json
solved the problem. So, final solution is:
render json: @my_model.to_hash.slice(:attr1, :attr2)
Upvotes: 1
Views: 604
Reputation: 5474
You may mix your initial approach (including AM serialization modules) with Erez' one as the documentation suggests.
class MyModel
include ActiveModel::Serialization::JSON
....
def attributes
{:attr1 => self.attr1.....}
end
...
end
Upvotes: 0
Reputation: 15788
I know it isn't straight forward but how about:
render :json => @my_model.attributes.slice(:attr1, :attr2)
You will also be required to define an attributes method as:
def attributes
{:attr1 => self.attr1.....}
end
Thanks for the comment bender.
Upvotes: 1
Reputation: 1428
I believe it's because Object::as_json is calling internally (look at this: http://apidock.com/rails/Object/as_json), and it has no options like :only or :except, so you can overide method to_hash in your class, e.g.:
def to_hash
{:attr1 => self.attr1, :attr2 => self.attr2}
end
and to_json will do exactly what you want.
Certainly, another option is to override method to_json ...
Upvotes: 0