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}}}}