简体   繁体   中英

Filter objects with many-to-many table in Rails using has_scope

There are two tables: User and Industry. User can relate to many industries and a lot of users belong to one Industry.

Industry.rb

class Industry <ApplicationRecord
    has_many: users,: through =>: industry_users
    has_many: industry_users
end

User.rb

class User <ApplicationRecord

  belongs_to: specialty
  has_many: industries,: through =>: industry_users
  has_many: industry_users

  scope: by_specialty, -> specialty {where (: specialty_id => specialty)}
  scope: by_period, -> started_at, ended_at {where ("graduation_date> =? AND graduation_date <=?", started_at, ended_at)}
end

IndustryUser.rb

The relationship between them is many_to_many. There is a third table IndustryUser which stores two columns.

class IndustryUser <ApplicationRecord
    belongs_to: user
    belongs_to: industry
end

Now I'm developing an API. I use has_scope gem to filter users by parameters in get request. Above, I successfully filtered them on the specialty and the date of graduation. For example, filtering on the specialty.

http://localhost:3000/v1/users?by_specialty=1

Filtering by the date of graduation. You should provide period of time.

http://localhost:3000/v1/users?
by_period[started_at]=20040101&by_period[ended_at]=20070101

I got stuck when I wanted to get users who belong to a particular industry. Here is an example of a get query

http://localhost:3000/v1/users?by_industry=2

For example. Here, I want it to render all users who are related to the second industry. Does anyone know how to filter objects that relate to many-to-many relations using has_scope?

I think it's going to be something like:

scope: by_industry, -> industry {User.joins(:industry_users).where(industry_users: {id: IndustryUser.where(industry: Industry.where(id: industry))})}

This bit finds the correct industry:

Industry.where(id: industry)

This bit finds IndustryUser records that reference the just-found Industry :

IndustryUser.where(industry: Industry.where(id: industry))

And then you join on the found industry_users to find User s that are reference by the industry_users .

User.joins(:industry_users).where(industry_users: {id: IndustryUser.where(industry: Industry.where(id: industry))})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM