I had a model which returns some parameters and includes parameters from other models as follows:
def as_json(options = {})
camelize_keys(super(options.merge(:only => [:id, :userId], include:{
comments: { only: [:test, :id] },
valediction: { only: [:name, :text, :hidden, :order] }
})))
end
def camelize_keys(hash)
values = hash.map do |key, value|
[key.camelize(:lower), value]
end
Hash[values]
end
Now I have moved the code to my controller because different controller actions need to return different parts of the model. (index should just return valediction, but show should return comments and valediction)
The new controller:
def index
respond_with(displayed_user.microposts.all, include: {
valediction: { only: [:name, :text] }
})
end
def show
respond_with(displayed_user.microposts.find(params[:id]), include: {
comments: { only: [:test, :id] },
valediction: { only: [:name, :text, :hidden, :order] }
})
end
But I'm very new to rails and I don't know how to put the camelize_keys function in so that it works.
You could move the method to a class method in the model, eg
#class methods
class << self
def camelize_keys(hash)
values = hash.map do |key, value|
[key.camelize(:lower), value]
end
Hash[values]
end
end
Now you can call this from anywhere like
MyModel.camelize_keys(some_hash)
Doing complex JSON formatting in your controllers / and or models usually leads to bloat and is a pain to test.
A good solution for this is using the ActiveModel::Serializer (AMS) gem. Its included in Rails 5 but you can easily add it to a Rails 4 project by adding it to the gemfile:
# See rubygems.org for latest verstion!
gem 'active_model_serializers', '~> 0.9.3'
Then run bundle install
and restart your rails server.
With AMS you create serializer classes which define how your model data should be represented in JSON, XML etc. A serializer is basically a class that takes a model instance (or an array of models) and returns a hash (or an array of hashes) when you call .serializable_hash
.
But Rails will take care of that part automatically for you.
class MicropostSerializer < ActiveModel::Serializer
attributes :id, :user_id
has_many :comments
has_many :valedictions
end
class CommentSerializer < ActiveModel::Serializer
attributes :test, :id
end
class ValedictionSerializer < ActiveModel::Serializer
attributes :name, :text, :hidden, :order
end
In your controller you can simply call:
def index
render json: displayed_user.microposts.all
end
camelize_keys
? Unless you have to support some weird legacy client that needs camelized keys there are very few reasons to do this. Most large API's use snakecase (Facebook, Google etc.) and Rails 5 is moving towards the JSONAPI spec which uses snakecase.
From your code sample it seems that some of your rails model attributes (and the db columns backing them) use camelcase. You should change the DB column with a migration as soon as possible.
If you HAVE to support a legacy database you can use alias_attribute:
class Pet < ActiveRecord::Base
alias_attribute :ownerId, :owner_id
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.