我在方法控制器中有这个渲染:
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
我在控制器中有参数。有没有办法将此参数传递给模型中的方法?
答案 0 :(得分:4)
不幸的是,传递需要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]
}
}
}
}
答案 1 :(得分:4)
所有答案都很好!
我做了类似的事情:
在控制器中:
boat.port.language = params[:language]
模特:
attr_accessor :language
@language
def translatedCity
city = TranslationService.translateCity(self.city_id, language)
return city.element_translation
end
您怎么看?
答案 2 :(得分:1)
as_json
不支持需要参数的方法,但这是一个使用Presenter(或装饰器或视图模型,取决于你与谁交谈)构建所需JSON的好地方。 Draper是一个宝石,如果你想要一个,它可以帮助你,你的控制器看起来像
data = @boats.map do |boat|
BoatPresenter.new(boat).as_json(language: params[:language])
end
render json: data
然后BoatPresenter
会在as_json
中添加您想要的额外数据:
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
)。
如果您反对添加课程,也可以直接在as_json
覆盖Boat
来处理language
选项:
def as_json(options = {})
super(options).tap do |json|
json[:translated_city] = translated_city(options[:language])
end
end
答案 3 :(得分:0)
您可以设置'语言'在会话变量中并在控制器中执行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}}}}