Рельсовые ассоциации - идеи для лучшей практики - PullRequest
5 голосов
/ 29 августа 2011

Вопрос по рельсовым ассоциациям.
Рассмотрим следующие модели:

  • Люди
  • События
  • Изображения

Люди и события могут иметь много изображений.
Изображения, загружаемые на событие, должны иметь возможность ассоциироваться с несколькими людьми.

Это означает, что между людьми и изображениями существует две взаимосвязи.
Тот, где изображения загружаются непосредственно на человека. И тот, где человек отмечен в событии.

Может ли быть также связь между person и event на основании того факта, что они были помечены на одном (или нескольких) изображениях в событии? В этом отношении это своего рода система маркировки изображений, в которой ассоциации создаются на основе событий, в которых люди отмечены.

Хотите знать, что является лучшей практикой в ​​Rails для создания этой ассоциации? Любая помощь или совет с благодарностью!

Ответы [ 3 ]

2 голосов
/ 29 августа 2011

Я не совсем уверен в лучшей практике, но есть шанс решить ваше дело простым способом, насколько я вас понимаю:

У нас есть:

Event ... has_many :photos; Photo ... belongs_to :event

и решение - создать некоторый промежуточный класс ActiveRecord

People ... has_many :photos, :through photo_mappings

PhotoMapping ... belongs_to :user; belongs_to :photo

Иметь хороший опыт AR ассоциации лучших * 1 1009 *

1 голос
/ 31 августа 2011

В рельсах определенно возможно определить объединяющую таблицу, которая имеет дополнительные поля. Так что в этом случае я бы определил следующую таблицу:

class LinkedImage
  belongs_to :person
  belongs_to :image

  OWNER=1
  TAGGED=2

  validates :relation_type, :inclusion => {:in => [OWNER, TAGGED]}
end

Эта таблица будет связывать изображение с человеком и имеет дополнительное поле relation_type (можно подумать о более подходящем имени, может быть), которое теперь может иметь два значения: 1 (для OWNER, что означает изображение было загружено непосредственно человеку) и 2 (человек помечен на изображении). Помимо отношения, возможно, вы захотите сохранить что-то дополнительное, например, положение на изображении, дополнительный комментарий, тогда вы можете легко добавить это и здесь.

И человек будет выглядеть так:

class Person
  has_many :linked_images
  has_many :uploaded_images, :class_name => Image, 
                             :through => :linked_images, 
                             :conditions => "relation_type=#{LinkedImage::OWNER}"
  has_many :tagged_in_images, :class_name => Image,
                              :through => :linked_images,
                              :conditions => 'relation_type=#{LinkedImage::TAGGED}"
end 

и код для Image могут быть похожими.

Надеюсь, это поможет.

0 голосов
/ 29 августа 2011

Я не знаю, является ли это лучшим подходом, но я бы сделал что-то вроде этого:

class User < ActiveRecord::Base
  has_many :images, :as => :owner
  has_many :tags
  has_many :tagged_images, :through => :tags, :source => :image

  has_many :tagged_events, :finder_sql => %q( SELECT `events`.* FROM `events`, `images` WHERE `events`.id = `images`.owner_id AND `images.owner_type ="Event" `
                                    WHERE (`images`.id IN (#{tagged_image_ids.join(',')}) ))


end

class Event < ActiveRecord::Base
  has_many :images, :as => :owner

  has_many :tagged_users, :finder_sql => %q( SELECT `users`.* FROM `users`, `images` WHERE `users`.id = `images`.owner_id AND `images.owner_type ="User" `
                                    WHERE (`images`.id IN (#{image_ids.join(',')}) ))


end

class Tag < ActiveRecord::Base
  belongs_to :user
  belongs_to :image  
end

class Image < ActiveRecord::Base
  belongs_to :owner, :polymorphic => true
  has_many :tags
  has_many :tagged_users, :through => :tags, :source => :user
end

Примечание. Использование finder_sql не является лучшим в Rails, потому что, например, оно не позволяет добавлять новые изображения с тегами, просто используя отношения, но прекрасно работает для чтения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...