Created
December 7, 2011 00:04
-
-
Save stevenharman/1440721 to your computer and use it in GitHub Desktop.
Find an item by id, and eagerly load association if the association exists. Possible?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # This is a record, as in a vinyl. | |
| class Record < ActiveRecord::Base | |
| belongs_to :user | |
| belongs_to :album | |
| end | |
| class Album < ActiveRecord::Base | |
| has_many :records | |
| belongs_to :artist | |
| end | |
| class User < ActiveRecord::Base | |
| has_many :records | |
| end | |
| class Artist < ActiveRecord::Base | |
| has_many :albums | |
| end | |
| # I want to query for a certain Album and also pull back any specific instances of | |
| # that album owned by a given User. However, if the user doesn't own any instances | |
| # of the Album, I still want the Album. Is that doable? | |
| # Example, find Album #42 and include any records owned by user #99. | |
| Album.include(:records).where('records.user_id' => 99).find(42) | |
| # this causes RecordNotFound if user 99 does NOT have any records for Album 42. |
Author
Author
Perhaps I should just bite the bullet and do it in two calls?
a = Album.find(42)
a_records = a.records.where('user_id' => 99)Yeah you're right. I had it backwards :).
I see what you're trying to do now. I think 2 queries is ok in this case. It's probably possible to do it in 1 though.
I believe find is not supposed to be mixed with the other query methods. It's single purpose, for getting 1 record.
What about this:
Album.include(:records).where('records.user_id = ? or records.user_id is null", 99).where(:id => 42).first definitely a shot in the dark.
Author
I was thinking the same thing, but it also results in an empty array. Also, I think I prefer using two queries, and sticking with the AR ARI, as it is more expressive and intention revealing.
Also, all of this is wrapped inside other objects - I treat the AR API as a private to the AR Models. For example
class Library
def initialize(user, fetch_albums=Album)
@owner = user
@fetch_albums = fetch_albums
end
def albums
fetch_albums.for_owner(owner)
end
def fetch_records_for_album(album)
owner.fetch_records_for_album(album)
end
private
attr_reader :owner, :fetch_albums
end
class Album < ActiveRecord::Base
has_many :records
belongs_to :artist
#...
def self.for_owner(owner)
includes(:records).where(user_id: owner)
end
end
class User < ActiveRecord::Base
has_many :records
#...
def fetch_records_for_album(album)
records.where(album_id: album)
end
end
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@subdigital Actually, I believe you have that backwards. see: http://guides.rubyonrails.org/active_record_querying.html#specifying-conditions-on-eager-loaded-associations