Ruby on Rails: belongs_to and has_many over the same pair on the same model
First, my model definitions:
class Certificate < ActiveRecord::Base
belongs_to :certificate_series
end
class CertificateSeries < ActiveRecord::Base
has_many :certificates
belongs_to :last_certificate_in_series, :class_name => "Certificate", :foreign_key => :last_certificate_in_series_id
end
I thought of the association as: CertificateSeries have many Certificates and have a Certificate which is the last one in the series. I've thought of using have_one, but according to the association basics, have_one is not correct based on where I put the associating key.
You can think of it as every time you get a new passport, the physical passport is changing (with its issuing and expiry date changing) but it is still a passport. Thus, you can have a lot of physical passports (certificates) but you only have 1 present passport (the last in the series, which is a physical passport) and the physical passports belong to the "passport" class of IDs (certificate series).
What I want is that I can call CertificateSeries.last_certificate_in_series and it will return the last certificate in the series. I thought of doing this in the db level by having the field last_certificate_in_series_id. I wanted to do it this way to reduce the database overhead of just getting 开发者_如何学运维the last one in the series. The other approach I thought of was get all the certificates in a series, arrange them by date, and get the most recent one.
Thus I'm now having problems trying to reflect this association in the models.
belongs_to :last_certificate_in_series, :class_name => "Certificate", :foreign_key => :last_certificate_in_series_id
seems not to define it properly. I can call CertificateSeries.last_certificate_in_series but it only returns a nilClass even when last_certificate_in_series_id is set to a valid value.
I'm open for suggestions on other approaches.
You might consider the acts_as_list plugin. Then in the certificate model:
belongs_to :certificate_series
acts_as_list :scope => certificate_series
You should create a method that returns the last certificate in series. You don't need to create another relationship for this.
class Certificate < ActiveRecord::Base
belongs_to :certificate_series
end
class CertificateSeries < ActiveRecord::Base
has_many :certificates
def last_certificate_in_series
certificates.last
end
end
Actually you don't need the extra belongs_to
association. It sounds very natural that the last certificate in the certificate_series.certificates
is the one you want. So you could simply do this:
class Certificate < ActiveRecord::Base
belongs_to :certificate_series
end
class CertificateSeries < ActiveRecord::Base
has_many :certificates
end
certificate_series.certificates.last
精彩评论