开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜