Outer Join The Rails 3 Way
i have 3 models like :
location, user, discovered_location(location_id,user_id)
I think i need an outer join in order to get all locations, as well as include the discovered_location model, if that location has been discovered by the user.
I would need something like {location1, location2, location3:includes disco开发者_运维问答vered_location, location4 ..}
Is there a Rails 3 way to do that ? If not, what is the best way ?
EDIT
I want to get the locations specified above, for a certain user. To better illustrate, it should be :
user {location1, location2, location3:includes discovered_location, location4 ..}
(A user has many discovered locations)
You can do an outer join in Rails only by using an SQL literal in the joins
method:
joins("OUTER JOIN table2 on table2.column = table1.column")
joins
makes an inner join, includes
makes an outer join.
http://guides.rubyonrails.org/active_record_querying.html#specifying-conditions-on-eager-loaded-associations
You need to check that the user id in your discovered_locations table is either equal to the id of the user in question, or is null. This is easily accomplished with the meta_where gem. Given the following models:
class User < ActiveRecord::Base
has_many :discovered_locations
has_many :locations, :through => :discovered_locations
end
class Location < ActiveRecord::Base
has_many :discovered_locations
has_many :users, :through => :discovered_locations
end
class DiscoveredLocation < ActiveRecord::Base
belongs_to :user
belongs_to :location
end
Insert some dummy data, then execute a statement such as this:
Location.includes(:discovered_locations).where(
{:discovered_locations => {:user_id => User.first.id}} |
{:discovered_locations => {:user_id => nil}}
).each do |loc|
puts "#{loc.name} #{loc.discovered_locations.empty? ? 'not visited' : 'visited'}"
end
精彩评论