Rails渲染json包括带参数的方法
我在方法控制器中有这个渲染:
render :json => @boats, :include => {:port => {:only => [:id, :name], :include => {:city => {:only => [:id, :name], :methods => :translatedCity}}}}
但是模型中的translatedCity
方法应该接受语言参数。
def translatedCity language = params[:language] puts "translatedCity.language=" + language city = TranslationService.translateCity(self.city_id, language) return city.element_translation end
我在控制器中有参数。 有没有办法将此参数传递给模型中的方法?
所有答案都很好!
我刚做了类似的事情:
在控制器中:
boat.port.language = params[:language]
在模型中:
attr_accessor :language @language def translatedCity city = TranslationService.translateCity(self.city_id, language) return city.element_translation end
你怎么看?
不幸的是,传递需要params to_json
方法的过程并没有很好地构建到rails中。 一个典型的模式是修改模型上的as_json
方法以接受自定义键,然后调用to_json
(或render :json
)
# city.rb model def translatedCity(language) puts "translatedCity.language=" + language city = TranslationService.translateCity(self.city_id, language) return city.element_translation end def as_json(options = {}) json_to_return = super if options.has_key? :translatedCity city_translation = self.translatedCity(options[:translatedCity][:language]) json_to_return[:translatedCity] = city_translation end return json_to_return end
现在在你的控制器中,你会认真地传递一切
render :json => @boats, :include => { :port => { :only => [:id, :name], :include => { :city => { :only => [:id, :name], :translatedCity => params[:language] } } } }
as_json
不支持需要参数的方法,但这是一个使用Presenter(或装饰器或视图模型,取决于你与谁交谈)构建所需JSON的好地方。 Draper是一个gem,如果你想要的话可以帮助它,你的控制器看起来像
data = @boats.map do |boat| BoatPresenter.new(boat).as_json(language: params[:language]) end render json: data
然后BoatPresenter
会在BoatPresenter
添加你想要的额外数据:
def as_json(options = {}) @boat.as_json(options).tap do |json| json[:translated_city] = @boat.translated_city(options[:language]) end end
如果你想要一个没有控制器担心的标准设置,你也可以让BoatPresenter
添加你的默认include
等。 如果您不想自己进行数组映射,Draper还会提供集合演示者(例如BoatsPresenter
)。
如果你反对添加一个类,你也可以直接在Boat
上覆盖as_json
来处理language
选项:
def as_json(options = {}) super(options).tap do |json| json[:translated_city] = translated_city(options[:language]) end end
您可以在会话变量中设置’language’并在控制器中执行to_json之前设置它,并在返回之前销毁方法中的会话,如下所示
def translatedCity(language=nil) language ||= session[:language] puts "translatedCity.language=" + language city = TranslationService.translateCity(self.city_id, language) session[:language] = nil #destroy session, or use session.delete(:language) return city.element_translation end session[:language] = language render :json => @boats, :include => {:port => {:only => [:id, :name], :include => {:city => {:only => [:id, :name], :methods => :translatedCity}}}}