Rails requests has_many: conditionally with multiple identifiers

I am trying to create a filtering system for a website where there are locations and functions through the LocationFeature model. Basically, what he should do is give me all locations based on a combination of function identifiers.

So, for example, if I call a method:

Location.find_by_features(1,3,4)

It should return only those places in which there are all selected functions. Therefore, if the location has feature_id [1, 3, 5], it should not be returned, but if it has [1, 3, 4, 5], it should. However, he currently provides me with locations in which either . Thus, in this example, it returns both values ​​because some of the feature_ids are present in each of them.

Here are my models:

class Location < ActiveRecord::Base
  has_many :location_features, dependent: :destroy
  has_many :features, through: :location_features

  def self.find_by_features(*ids)
    includes(:features).where(features: {id: ids})
  end
end

class LocationFeature < ActiveRecord::Base
  belongs_to :location
  belongs_to :feature
end

class Feature < ActiveRecord::Base
  has_many :location_features, dependent: :destroy
  has_many :locations, through: :location_features
end

, , , . , :

Location.includes(:features).where('features.id = 5 AND features.id = 9').references(:features)

. OR AND, . :

Location.includes(:features).where(features: {id: 9}, features: {id: 1})

feature_id 1.

, ?

+2
2

. , .

scope :has_all_features, ->(*feature_ids) {
  where( ( ["locations.id in (select location_id from location_features where feature_id=?)"] * feature_ids.count).join(' and '), *feature_ids)
}
+1

include, "-" , A B, foreign_key. ( ​​ (feature_locations), .)

, features.id = 9 AND features.id = 1. features.id.

, : location_features, feature_id. , feature_id location_id .

, , , location_ids ( ), , : ( )

#in Location
def self.having_all_feature_ids(*ids)
  location_ids = Feature.find_all_by_id(ids).map(&:location_ids).inject{|a,b| a & b}
  self.find(location_ids)
end

1: *ids , ( , " " ) .

2: inject - . : " , , .., . , (a b), " & ", " " - , . , , , , . , .

EDIT: , sql- - , group_concat, , , :)

+2

Source: https://habr.com/ru/post/1652302/


All Articles