假设我有3个相互关联的模型:
class Farm < ApplicationRecord
has_many :horses
has_many :events
end
class Horse < ApplicationRecord
belongs_to :farm
has_many :events_horses, class_name: 'Event::EventsHorse'
has_many :events, through: :events_horses, source: :event, dependent: :destroy
end
class Event
belongs_to :farm
has_many :events_horses, class_name: 'Event::EventsHorse'
has_many :horses, through: :events_horses, source: :horse, dependent: :destroy
end
class Event::EventsHorse < ApplicationRecord
self.table_name = "events_horses"
belongs_to :horse
belongs_to :event
audited associated_with: :event, except: [:id, :event_id]
end
如何确保每匹马都属于同一农场?可能的解决方案是使用自定义验证,但我想知道是否还有其他方法。我还没有其他类似Horse的模型,因此它迫使我对每个模型进行自定义验证方法。
class Event
...
validate :horses_belongs_to_farm
private
def horses_belongs_to_farm
horses.all? {|h| h.farm_id == farm_id}
end
end
答案 0 :(得分:2)
我认为您使用的模型在需要一致性检查的表之间设置了过多的ID。
如果您以此方式设置模型,则无需验证马场和事件是否一致,因为数据可以确保这一点:
class Farm < ApplicationRecord
has_many :horses
has_many :events
end
class Horse < ApplicationRecord
belongs_to :farm
has_many :events, through: :farm
end
class Event < ApplicationRecord
belongs_to :farm
has_many :horses, through: :farm
end
如果您需要有效地访问事件中的马或事件中的马,则可以使用联接。这提供了一些简单性,清晰度和一致性。
您还应该看看Choosing Between has_many_through
and has_and_belongs_to_many
。
Event
模型中会导致多余的验证。由于您的目的是确保在给定的情况下,马匹和农场保持一致,因此我将验证放在EventsHorses
中:
class Event::EventsHorse < ApplicationRecord
...
validate :horse_belongs_to_farm
private
def horse_belongs_to_farm
horse.farm_id == event.farm_id
end
end
顺便说一句,您是否拥有Event::EventsHorse
而不是简单地拥有EventsHorse
的单独模型?