2009-07-29 3 views
1

У меня есть две модели ActiveRecord с hasMany/belongsTo ассоциации:Использование ActiveRecord belongs_to с двумя ключами

class User < ActiveRecord::Base 
    has_many :letters 
end 

class Letter < ActiveRecord::Base 
    belongs_to :user 
end 

Модель Пользователь имеет revision_number атрибут, к которому я хотел бы определения области belongs_to ассоциации, поэтому письмо связан с пользователем как user.id, так и user.revision_number.

Я попытался с помощью: ключевые условия, как документированы в API документации:

class Letter < ActiveRecord::Base 
    belongs_to :user, :conditions => "revision_number = #{client_revision}" 
end 

, но это пытается вызвать клиент-версию на классе Letter, а не экземпляр Letter. Может ли кто-нибудь указать мне в правильном направлении для правильного определения ассоциации belongs_to?

Я использую плагин acts-as-revisable для версии модели пользователя.

ответ

0

Наконец понял, что мне нужно было что-то вроде составных ключей, которые Rails ActiveRecord не поддерживает. Решение (пока по крайней мере) было писать пользовательские клиентские аксессоров Письмо для поддержки составных ключей (идентификаторов и revision_number):

class Letter < ActiveRecord::Base 
    def client 
    Client.find_by_id(self.client_id).try(:find_revision, self.client_revision) 
    end 

    def client=(c) 
    self.client_id = c.id 
    self.client_revision = c.revision_number 
    end 
end 

class Client < ActiveRecord::Base 
    acts_as_revisable 

    has_many :letters 
end 

С этой установкой клиента # 1.letters будет получить массив как письма, но Письмо # 2.client извлечет клиента # 1R2, в то время как письмо # 2.client извлечет Client # 1r4:

Client   id: 1 1 1 1 1 1 
     rev_number: 1 2 3 4 5 6 

Letter   id:   1    2 
     client_id:   1    1 
    client_revision:   2    5 

до сих пор не уверен, что это лучший подход к этой проблеме, но, кажется, работа на данный момент.

0

У меня возникли проблемы с пониманием того, почему вы хотели бы охватить belongs_to таким образом. Поправьте меня, если я ошибаюсь, но было бы лучше сделать что-то подобное. Я предполагаю, что вы хотите какой-то системы управления версиями:

class User < ActiveRecord::Base 
    has_many :letters 
end 

class Letter < ActiveRecord::Base 
    has_many :revisions, :class_name => "LetterVersion" 
    belongs_to :current, :class_name => "LetterVersion" 
end 

class LetterVersion < ActiveRecord::Base 
    belongs_to :letter 
end 
+0

Если вы хотите, вы можете обладать текущим значением до последней версии updated_at и использовать has_one. Это позволит избежать добавления другого внешнего ключа в модель письма. –

+0

Привет, Спасибо за ваши ответы. Я использую плагин act_as_revisable. В моей базе данных пользователи версируются так, что любые изменения в пользовательской модели проверяются. Письма не являются версиями. Текст письма содержит связанные значения, например имя пользователя. При просмотре письмо должно отображать имя клиента во время создания письма. Возможно, лучшим примером может служить продукция по счетам-фактурам; цена продукта должна быть зафиксирована в счете-фактуре, так что просмотр счета-фактуры в течение нескольких месяцев после строки покажет правильную цену в момент создания счета-фактуры. Спасибо, Chris –

Смежные вопросы