Четырехстороннее дерево ассоциаций Ruby on Rails

Общая картина: я создаю приложение для исторического отслеживания временных событий. Я настраиваю его с помощью четырех основных моделей: Пользователи, События, Истории и Изображения. Идея состоит в том, что любой пользователь может создать событие и добавить истории и/или изображения в свое или любое другое событие. Но и Истории, и Изображения всегда привязаны к определенному Событию, а любая другая модель принадлежит создавшему ее Пользователю (для целей фильтрации и редактирования)

Общая структура ассоциаций будет примерно такой:

class User < ActiveRecord::Base
  has_many :events
  has_many :stories
  has_many :images
end

class Event < ActiveRecord::Base
  belongs_to :user
  has_many :stories
  has_many :images
end

class Story < ActiveRecord::Base
  belongs_to :user
  belongs_to :event
end

class Image < ActiveRecord::Base
  belongs_to :user
  belongs_to :event
end

Я новичок в Rails, и у меня практически нет контроля над более сложными ассоциациями, такими как many_to_many, through: или as:

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


person GarciadelCastillo    schedule 06.09.2013    source источник


Ответы (2)


Вы на правильном пути, но story и image не должны принадлежать user. Вы создаете избыточность там.

class User < ActiveRecord::Base
  has_many :events
  has_many :stories, :through => :events
  has_many :images, :through => :events
end

class Event < ActiveRecord::Base
  belongs_to :user
  has_many :stories
  has_many :images
end

class Story < ActiveRecord::Base
  belongs_to :event
end

class Image < ActiveRecord::Base
  belongs_to :event
end

Таким образом, вы все еще можете писать user.stories и user.images.

person Marcelo De Polli    schedule 06.09.2013
comment
Я вижу, очень интересно. Но последний вопрос: подразумевает ли установка :through выше, что только пользователь, создавший событие, может владеть содержащимися в нем историями и изображениями? Потому что это будет случай, когда пользователь A создал событие, но пользователь B добавил к нему историю, а пользователь C прикрепил два изображения к этому же событию, каждая переплетенная модель затем принадлежит разным пользователям... - person GarciadelCastillo; 06.09.2013
comment
Я думаю, вы путаете авторизацию с моделью данных. Возможность обновлять атрибуты не имеет ничего общего с модельными отношениями. Вполне возможно, что другой пользователь будет добавлять изображения в экземпляр Event, но пока они относятся к одному и тому же событию, story.event.user всегда будет одним и тем же. - person Marcelo De Polli; 06.09.2013
comment
Большое спасибо @depa, попробую посмотреть, как это работает! Я предполагаю, что тогда story.event.user будет отличаться от story.user? - person GarciadelCastillo; 06.09.2013
comment
Теперь, если вы на самом деле хотели, чтобы истории и изображения принадлежали разным пользователям, отличным от владельца события, тогда мы бы говорили о чем-то другом. - person Marcelo De Polli; 06.09.2013
comment
Хорошо, тогда, возможно, я не правильно объяснил, но это именно то, что я имею в виду. ;) - person GarciadelCastillo; 06.09.2013
comment
Хаха, хорошо. Тогда ваши первоначальные ассоциации будут работать просто отлично. Может быть, просто используйте belongs_to :owner, :class_name => 'User' в Event, чтобы не путать его с другим видом владения. - person Marcelo De Polli; 06.09.2013
comment
Звучит здорово, большое спасибо @depa. Попробую и приму, если работает! - person GarciadelCastillo; 06.09.2013
comment
Круто, но в ассоциацию нужно добавить external_key: belongs_to :owner, :class_name => 'User', :foreign_key => 'user_id' - person GarciadelCastillo; 07.09.2013

Попробуйте использовать вложенные атрибуты:

http://railscasts.com/episodes/196-nested-model-form-part-1

Образец кода:

class User < ActiveRecord::Base
  has_many :events
  accepts_nested_attributes_for :events
end

class Event < ActiveRecord::Base
  belongs_to :user
  has_many :stories
  has_many :images
  accepts_nested_attributes_for :stories, :images
end

class Story < ActiveRecord::Base
  belongs_to :event
end

class Image < ActiveRecord::Base
  belongs_to :event
end

Вложенные атрибуты принимают многие уровни. В данном случае есть 3 уровня

  1. пользователь

  2. мероприятие

  3. история и образ.

Это похоже на образец на rails cast с 3 уровнями (опрос - вопрос ответ).

Перейдите по ссылке выше и посмотрите часть 2, чтобы увидеть как это работает.

Или вы не можете посмотреть на мой образец, но он работает с 2 уровнями (тема - задача).

Ссылка на здесь

Войти под учетной записью: [email protected]/12341234

person Duyet Nguyen    schedule 30.11.2016