【问题标题】:Rails Query to return users belongs to any cities & not belong to any citiesRails查询返回用户属于任何城市而不属于任何城市
【发布时间】:2016-07-18 14:50:54
【问题描述】:

我在两个表之间有Many to Many Associations:对于前用户和城市

users
id  name
1   Bob
2   Jon
3   Tom
4   Gary
5   Hary

cities
id     name 
1      London
2      New-york
3      Delhi

users_cities
id   user_id   city_id
1    1         2
2    2         1
3    3         1
4    3         2
5    4         3

我想要两个 sql 查询

接受city_id数组并返回所有用户属于该城市的查询。 对于 Ex 当 city_id : [1, 2] 那么结果应该是 O/P 应该是

   id  name
    1   Bob
    2   Jon
    3   Tom

接受city_id数组的查询,返回所有不属于这些城市的用户。 对于 Ex 当 city_id : [1, 2] 那么结果应该是 O/P 应该是

    id  name
    4   Gary
    5   Hary

注意:-我正在使用

user.rb

has_and_belongs_to_many :cities

city.rb

has_and_belongs_to_many :users

【问题讨论】:

    标签: ruby-on-rails-3 ruby-on-rails-4 activerecord postgresql-9.1 has-and-belongs-to-many


    【解决方案1】:

    基本上你需要两个方法/范围

    class User < ActiveRecord::Base
      has_and_belongs_to_many :cities
    
      scope :by_cities, ->(city_ids) {includes(:cities).where(cities: {id: city_ids}).distinct}
    
      # There are several ways to do that
      # 1. That will return all not associated records but that we won't need
      # In this scenario, You need OR condition like city_ids OR NULL 
      # This will return => ["Hary"] 
      scope :not_by_cities, -> {includes(:cities).where(cities: {id: nil})}
    
      # 2. Need to create a scope in City model
      # scope :city_ids, -> all.pluck(:id) 
      # This will return => ["Gary", "Hary"] 
      scope :not_by_cities, -> {includes(:cities).where(cities: {id: [City.city_ids - city_ids, nil]})}
    
      # 3. If you are on Rails 5, It is much more easier
      # This will return => ["Gary", "Hary"] 
      scope :not_by_cities, -> {includes(:cities).where.not(cities: {id: city_ids}).where(cities: {id: nil})} 
    end
    

    对于选项 2

    class City < ActiveRecord::Base
        has_and_belongs_to_many :cities
        scope :city_ids, -> {all.pluck(:id)}
     end
    

    结果:

    >> User.by_cities([1,2]).pluck(:name)
    => ["Bob", "Jon", "Tom"]
    
    >> User.not_by_cities.pluck(:name)
    => ["Gary", "Hary"] 
    

    如果您是 Rails 4.x 并且仍然想要一些简单的解决方案。使用那里的任何人

    希望这会对你有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-05
      相关资源
      最近更新 更多