Rails as_json包含条件

Xia*_*ong 7 conditional json ruby-on-rails include

我有问题限制动态属性的as_json包含:

@pirates_ships = @current_account.pirates.as_json(:include => {:ships => {:only => [:id, :name]}}, :only => [:id, :last_name])
Run Code Online (Sandbox Code Playgroud)

这肯定会给我所有海盗带或不带他们的船.

但我还需要通过例如ships.ocean_id限制船只

我尝试通过条件解决它:

pirates.includes(:ships).where("ships.ocean_id = ?", @ocean.id).as_json(...)
Run Code Online (Sandbox Code Playgroud)

限制有效,但现在所有没有船只的海盗都会丢失.

我自己的JOIN语法也没有运气.

有任何想法吗?趣多多

UPDATE

到目前为止我的解决方案是手动加载.这样我可以拥有自己的动态条件:

@pirates = @current_account.pirates
@ships = @current_account.ships.where({:pirate_id.in => @pirates, :ocean_id => @ocean.id})

render :json => { :pirates => @pirates.as_json(...), :ships => @ships.as_json(...) }
Run Code Online (Sandbox Code Playgroud)

我的Ajax回调现在可以迭代:盗版并为每个海盗添加他的船只(如果有的话).(我使用JS模板引擎clientide从JSON响应生成视图)

不是很优雅,但性能在我的情况下很重要.

我仍然愿意接受更好的想法.我尝试了动态的has_many:ships,:conditions => ......但这有点繁琐.

Dyl*_*kow 3

我认为你最好的选择是@pirates_ships在生成散列后更改散列as_json(我尝试了包含等的多种变体,但无法让任何东西发挥作用)。

@pirates_ships = @current_account.pirates.as_json(:include => :ships)
@pirates_ships.each do |pirate|
  pirate[:ships].delete_if{ |ship| ship.ocean_id != @ocean.id }
end

# Now, @pirates_ships should contain ALL pirates, as well as ships for @ocean
Run Code Online (Sandbox Code Playgroud)