I have problems to restrict an as_json include by a dynamic attribute:
@pirates_ships = @current_account.pirates.as_json(:include => {:ships => {:only => [:id, :name]}}, :only => [:id, :last_name])
This for sure gives me all pirates with or without their ships.
But I also need to restrict the ships by e.g. ships.ocean_id
I tried resolving it by includes with conditions:
pirates.includes(:ships).where("ships.ocean_id = ?", @ocean.id).as_json(...)
The restriction works, but now all pirates without a ship are lost.
Also no luck with my own JOIN Syntax.
Any ideas? Ahoy
UPDATE
My solution so far is to manually eager load. This way I can have my dynamic conditions:
@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(...) }
My Ajax callback can now iterate over :pirates and add for each pirate his ships if any. (I use a JS template engine clientside to generate the view from the JSON response)
Not very elegant, but performance is important in my case.
I'am still open for better ideas. I tried dynamic has_many :ships, :conditions => ... but that's a bit fiddly.
I think your best bet would be altering the @pirates_ships
hash after generating it from as_json
(I tried multiple variations of includes, etc. and couldn't get anything to work).
@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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With