Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to apply WHERE filter when calling to_json preserving the :includes

I have the followin 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 fields of the v3_passengers model before rendering it as json (for example "where v3_passenger.id = 2345")

I have tried this

render :json => enterprise.includes(:v3_passengers).where(enterprise_country: Thread.current['CurrentBehaviour'].COUNTRY).includes(:cost_center, :restrictions).to_json

But is not working, I have looked arround whitout any look in how to achieve this.

UPDATE

This are how the models are related

class Enterprise < ActiveRecord::Base
    has_many :v3_passengers


class V3Passenger < GlobalDB
    has_many :restrictions
    belongs_to :cost_center
like image 737
Mauricio Gracia Gutierrez Avatar asked Feb 11 '23 14:02

Mauricio Gracia Gutierrez


2 Answers

1. First you need to filter by joins or includes:

foo = enterprise.joins(:v3_passengers).where(v3_passengers: {enterprise_country: Thread.current['CurrentBehaviour'].COUNTRY})

or (prefered includes, since you are going to need v3_passengers )

foo = enterprise.includes(:v3_passengers).where(v3_passengers: {enterprise_country: Thread.current['CurrentBehaviour'].COUNTRY})

2. Then include the other nodes you need in the 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] } ])
like image 152
mohameddiaa27 Avatar answered Feb 15 '23 11:02

mohameddiaa27


The problem is that:

model.includes(:other_model).to_json

Isn't the same as:

model.to_json(include: :other_model)

So your first attempt is giving you all the fields of Enterprise, V3Passenger, Restriction and CostCenter in the output. Your second attempt is just giving you fields of Enterprise.

One potential fix is:

enterprise.joins(:v3_passengers).where("v3_passengers.id=?",2345).to_json(include: :v3_passengers)

(Including the other tables of course.)

This will give you JSON for all the Enterprises with v3_passengers.id=2345, including JSON for all their V3Passengers (even the V3Passengers who don't have id 2345).

If you only want to include V3Passengers who match the where clause then you need to add a scoped association to the model:

has_many :v3_passengers_where_id_2345, -> { where id: 2345 }

And then use that association when doing the JSON conversion:

enterprise.joins(:v3_passengers).where("v3_passengers.id=?",2345).to_json(include: :v3_passengers_where_id_2345)

This will give you JSON for enterprises who have v3_passengers.id=2345, including only their V3Passengers who have id 2345.

like image 25
Dave Slutzkin Avatar answered Feb 15 '23 09:02

Dave Slutzkin