Reputation: 3259
I have the following Ruby on Rails entity:
Playlist:
class Playlist < ActiveRecord::Base {
:id => :integer,
:name => :string,
:created_at => :datetime,
:updated_at => :datetime,
:dimension => :string,
:title => :string,
:text => :string,
:price => :float,
:playlist_image_file_name => :string,
:playlist_image_content_type => :string,
:playlist_image_file_size => :integer,
:playlist_image_updated_at => :datetime,
:main => :boolean,
:action => :string,
:hairdresser_id => :integer
}
And Keyword:
class Keyword < ActiveRecord::Base {
:id => :integer,
:name => :string,
:created_at => :datetime,
:updated_at => :datetime,
:preselected => :boolean
}
The relation between them is very simple: basically a Playlist object can have 0 or more keywords associated. Those are the models:
class Keyword < ActiveRecord::Base
has_and_belongs_to_many :playlists
end
class Playlist < ActiveRecord::Base
has_and_belongs_to_many :keywords
has_attached_file :playlist_image, styles: {medium: "500x500", small: "200x200", thumb: "40x40"}, default_url: "/system/playlist_default.jpg"
validates_attachment_content_type :playlist_image, content_type: /\Aimage\/.*\Z/
end
That allows me to do something like that:
Playlist.first.keywords
and retrieve all the keywords associated with the first playlist.
Now I would like to build a function to return all the playlists that have certain words as keywords and have "main" equals to true. For example all the playlist that have the keyword "Summer". I tryed with that:
Playlist.where(:main => true).map{|x| x.keywords.include? "Summer"}
But that returns only an array containing true or false depending if the related Playlist contains or not the keyword "Summer", I'm looking for something that return the whole playlist only if the array of keywords of that playlist include the word "summer". How can I achieve that?
Upvotes: 1
Views: 2859
Reputation: 373
You should create scopes to increase reusability.
class Playlist < ActiveRecord::Base
has_and_belongs_to_many :keywords
scope :main, -> { where(main: true) }
scope :with_key_words, -> (key_words) { joins(:keywords).where(keywords: {name: key_words}) }
end
To get all playlists satisfy your requirements, just:
Playlist.main.with_key_words(['Summer'])
Upvotes: 0
Reputation: 44581
Something like this should work, using includes
:
Playlist.includes(:keywords)
.where(playlists: {main: true}, keywords: {name: 'Summer'})
Upvotes: 2