2013-12-08 4 views
0

У меня есть таблица, называемая активами, которая имеет множество версий. Версии имеют номера версий. У каждого актива также есть столбец version_number, который указывает самую последнюю (новейшую) версию.Rails - has_one ассоциация с двумя параметрами

Я хотел бы установить связь между активом и его последней версией, но я не могу найти документацию о том, как это сделать. Было бы, в теории, искать что-то вроде этого

asset.rb

has_one :latest, class_name: "Version", foreign_key: ["asset_id", "version_number"], primary_key: ["id", "version_number"] 

Наивный подход будет:

asset.rb

def latest 
    Version.where(asset_id: asset.id, version_number: asset.version_number).first 
end 

Проблема с делать это просто в коде, однако, заключается в том, что я не могу загрузить «последний» в ассоциации_cache актива. Я также не могу легко загружать все связанные «последние» записи при загрузке набора активов, например Asset.includes(:latest).where(project_id: 7).

Причина, по которой я думаю, что это должно быть возможно потому, что полиморфные ассоциации используют два параметра.

ответ

0

Я действительно обнаружил решение после ввода моего вопроса, что помогло мне сформулировать вопрос лучше. Решение поступило любезно http://pivotallabs.com/rails-associations-with-multiple-foreign-keys/

TLDR;

has_one :latest, class_name: 'Version', foreign_key: :asset_id, primary_key: :id, conditions: Proc.new{|join_association| 
    if join_association 
    "versions.version_number = assets.version_number" 
    else 
    {version_number: version_number} 
    end 
} 

мне пришлось подправить линию "versions.version_number = version_number" немного, потому что в некоторых нетерпеливых-погрузочных ситуациях, SQL будет жаловаться на неоднозначность для ключа version_number. Итак, я добавил assets., чтобы устранить эту двусмысленность и устранить проблему. Я снова повторю то, что они говорят, а это значит, что вы должны joins(:latest) всякий раз, когда вы includes(:latest)!

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