I'm trying to do a "virtual relationship" (what I call it - don't know if there's a real term for it) in Rails. Here's one that I have that is definitely working: Address belongs_to Business and Business has_many Addresses. Addresses have a 'category' column: either Mailing or Physical. In theory, a business could have any number of each type, but in practice they have exactly one of each. So my models look like this:
class Address < ActiveRecord::Base
belongs_to :business
end
class Business < ActiveRecord::Base
has_many :addresses
has_one :physical_address, :class_name => 'Address', :conditions => ["category = ?", "Physical"]
has_one :mailing_address, :class_name => 'Address', :conditions => ["category = ?", "Mailing"]
end
Thus, I have two "virtual" has_one's, so that I can conveniently access either one (as business.physical_address or business.mailing_address) without having to do the work of separating them myself.
Now I'm trying to do something similar, but with a has_many :through. Here's my new scenario. I have a simple many-to-many relationship with a join. Let's say A has many J's, B also has many J's, and J belongs_to both A and B. However, A also has_many B's through J. So I can access them as a.bs.
However, the entries in B also have a 'category'. So as with the Business/Address example above, I want to have "virtual" has-one/many-through relationships in A, so I don't have to manually separate the B's by category. I tried something like this (assuming A's have exactly one B with category='Type 1'):
class A < ActiveRecord::Base
has_many :js
has_many :bs, :through => js
has_one :b_type1, :class_name => 'B', :through => :js, :conditions => ["category = ?", "Type 1"]
end
However, when I do a find on A's, the resulting objects do not have a b_type1 property in them.
Is it even possible to do what I'm trying to do?? Any help is appreciated.
Edit: I am needing this to be serialized to an Adobe Flex frontend (using the RestfulX framework). According to this thread, I can't use just a method as @Andrew suggests below because the resulting object will not get properly serialized without some heavy-duty effort.
The has_one association you wrote should work exactly as you want it, however Rails won't be able to guess the field from :b_type1.
Just as you explicitly specified the class name, try specifying the source:
has_one :b_type1, :class_name => 'B', :through => :js, :source => bs, :conditions => ["category = ?", "Type 1"]
I tested a similar finder and it worked as you would expect it to.