How to apply a WHERE filter when calling to_json that preserves: includes
I have the following Ruby + Rails code
render :json => enterprise.to_json(:include => { :v3_passengers => { :include => [:cost_center, :restrictions]}})
And I need to apply a WHERE filter using one of the v3_passengers model fields before passing it as json (eg "where v3_passenger.id = 2345")
I tried this
render :json => enterprise.includes(:v3_passengers).where(enterprise_country: Thread.current['CurrentBehaviour'].COUNTRY).includes(:cost_center, :restrictions).to_json
But doesn't work, I've looked around any look at how to achieve this.
UPDATE
Here's how the models are linked:
class Enterprise < ActiveRecord::Base
has_many :v3_passengers
class V3Passenger < GlobalDB
has_many :restrictions
belongs_to :cost_center
source to share
1. First you need to filter joins
either includes
:
foo = enterprise.joins(:v3_passengers).where(v3_passengers: {enterprise_country: Thread.current['CurrentBehaviour'].COUNTRY})
or (preferred includes, as you need v3_passengers
)
foo = enterprise.includes(:v3_passengers).where(v3_passengers: {enterprise_country: Thread.current['CurrentBehaviour'].COUNTRY})
2. Then include
other nodes that you need in to_json
:
foo.to_json(include: [v3_passengers: { include: [:cost_center, :restrictions] } ])
Final result:
render :json => enterprise.joins(:v3_passengers).where(v3_passengers: {enterprise_country: Thread.current['CurrentBehaviour'].COUNTRY}).to_json(include: [v3_passengers: { include: [:cost_center, :restrictions] } ])
source to share
The problem is that:
model.includes(:other_model).to_json
Not the same as:
model.to_json(include: :other_model)
So, your first try is to provide you with all the Enterprise, V3Passenger, Restriction and CostCenter outlets. Your second attempt is to simply provide you with Enterprise fields.
One potential fix:
enterprise.joins(:v3_passengers).where("v3_passengers.id=?",2345).to_json(include: :v3_passengers)
(Including other tables, of course.)
This will give you JSON for all businesses with v3_passengers.id = 2345, including JSON for all of their V3Passengers (even V3Passengers that don't have an ID of 2345).
If you want to include V3Passengers that match the where clause, you need to add a constrained binding association to the model:
has_many :v3_passengers_where_id_2345, -> { where id: 2345 }
And then use this association when doing your JSON transformation:
enterprise.joins(:v3_passengers).where("v3_passengers.id=?",2345).to_json(include: :v3_passengers_where_id_2345)
This will give you JSON for businesses that have v3_passengers.id = 2345, including only their V3Passengers that have ID 2345.
source to share
The second picture is close to the working version.
render :json => enterprise.v3_passengers.where(enterprise_country: Thread.current['CurrentBehaviour'].COUNTRY).includes(:cost_center, :restrictions).to_json
Try to use some kind of attitude. For a clearer answer, add your key models, Entrepreneurship and Passenger models.
source to share
if you want enterprise attributes in the resulting json:
render :json => enterprise.joins(:v3_passengers).where("v3_passengers.enterprise_country = ?", Thread.current['CurrentBehaviour'].COUNTRY).to_json(include: [v3_passengers: { include: [:cost_center, :restrictions] } ])
if you just need passengers:
render :json => enterprise.v3_passengers.where(enterprise_country: Thread.current['CurrentBehaviour'].COUNTRY).includes(:cost_center, :restrictions).to_json( include: [:cost_center, :restrictions])
source to share