2017-01-12 2 views
0

Я делаю приложение для просмотра фильмов. Пользователь может просматривать различные просмотренные обзоры и сохранять их в списке. В моей консоли я не могу получить доступ к спискам отзывов пользователей. User.list.reviews. Что мне не хватает? Заранее спасибо!!Помощь Ассоциации в Rails

Вот мои текущие модели и ассоциации.

пользователя Модель

has_one :list 
has_many reviews, :through => :list 

Список Модель

belongs_to :user 
has_many :reviews 

Обзор Модель

has_many :lists 
has_many :users, :through => :lists 

Схема: Список

user_id 
review_id 
+0

Пожалуйста, упростите свой вопрос, что вы ищете ..? – Milind

+0

Извините. Я пытаюсь создать список в своем приложении, который включает в себя отзывы из моей модели обзора. У каждого пользователя есть один список, который может иметь несколько обзоров. Я зациклился на том, как сделать мои ассоциации. Моя таблица списка - это объединенная таблица с review_id и user_id. В настоящее время, когда я пытаюсь получить доступ к отзывам в списке пользователей, я получаю эту ошибку - o такой столбец: reviews.list_id – hangloos

+0

В этом смысл? Извините за путаницу. – hangloos

ответ

2

В вашей схеме список имеет один идентификатор пользователя и один идентификатор проверки. Таким образом, в списке может быть только одна из этих вещей. Но вы хотите, чтобы у Пользователя был только один Список, в то время как в Списке много Обзоров.

Затем он становится более сложным, потому что в списке может быть много отзывов. Но поскольку многие пользователи могут помещать обзоры в свои собственные списки, один обзор может отображаться в нескольких списках. Короче говоря, список has_and_belongs_to_many :reviews и обзор has_and_belongs_to_many :lists. Это означает, что вам нужно где-то поместить идентификатор списка и идентификатор отзыва, которые выражают это отношение, - это называется таблицей объединения . Соглашение просто объединяет два имени связанных двух таблиц, чтобы получить имя таблицы соединений, поэтому, если у нас есть таблицы lists и reviews, нам нужна таблица соединений, которая называется lists_reviews (вы можете переопределить это, но проще просто пойти с конвенция).

Голый минимум Rails миграции будет:

create_table :users do |t| 
end 

create_table :lists do |t| 
    t.belongs_to :user # Leads to "user_id" column 
end 

create_table :reviews do |t| 
end 

create_table :lists_reviews do |t| 
    t.belongs_to :list # Leads to a "list_id" column 
    t.belongs_to :review # Leads to a "review_id" column 
end 

Учитывая это, и учитывая, что с #has_one вы должны положить #belongs_to в вещи у него есть, тоже, так что список должен belong_to :user, мы получим:

class User < ActiveRecord::Base # Rails <= v4 
    has_one :list 
    has_many :reviews, :through => :list 
end 

class List < ActiveRecord::Base 
    belongs_to :user 
    has_and_belongs_to_many :reviews 
end 

class Review < ActiveRecord::Base 
    has_and_belongs_to_many :lists 
    has_many :users, :through => :lists 
end 

И все это бросили в пустой Rails оболочки мы можем проверить его на консоли:

u1 = User.new; u1.save! 
u2 = User.new; u2.save! 

l1 = List.new(user: u1); l1.save! 
l2 = List.new(user: u2); l2.save! 

r1 = Review.new; r1.save! 
r2 = Review.new; r2.save! 
r3 = Review.new; r3.save! 

l1.reviews << r1 
l1.reviews << r2 
l1.save! 

l2.reviews << r2 
l2.reviews << r3 
l2.save! 

u1.list 
# => #<List id: 1, user_id: 1> 
u1.list.reviews 
# => #<ActiveRecord::Associations::CollectionProxy [#<Review id: 1>, #<Review id: 2>]> 
u2.list 
# => #<List id: 2, user_id: 2> 
u2.list.reviews 

# => #<ActiveRecord::Associations::CollectionProxy [#<Review id: 2>, #<Review id: 3>]> 
l1.user 
# => #<User id: 1> 
l2.user 
# => #<User id: 2> 

r1.users 
=> #<ActiveRecord::Associations::CollectionProxy [#<User id: 1>]> 
r1.lists 
=> #<ActiveRecord::Associations::CollectionProxy [#<List id: 1, user_id: 1>]> 
r2.users 
=> #<ActiveRecord::Associations::CollectionProxy [#<User id: 1>, #<User id: 2>]> 
r2.lists 
=> #<ActiveRecord::Associations::CollectionProxy [#<List id: 1, user_id: 1>, #<List id: 2, user_id: 2>]> 
r3.users 
=> #<ActiveRecord::Associations::CollectionProxy [#<User id: 2>]> 
r3.lists 
=> #<ActiveRecord::Associations::CollectionProxy [#<List id: 2, user_id: 2>]> 

... это работает.

+0

Один комментарий для последующего действия - вышеупомянутое также означает, что вы можете изменить 'has_one' на' has_many' и, таким образом, 'has_many: reviews,: through =>: lists', отмечая множественное число в' lists'. Теперь у пользователя будут списки, а не только один список. Вам не нужно будет менять свои данные, но у вас будет 'user.lists' вместо' user.list'. Вы бы сделали, например. 'user.list [0] .reviews' вместо просто' user.list.reviews', а 'user.reviews' будет возвращать полную коллекцию каждого Рецензирования через каждый Список, принадлежащий Пользователю. Вы никогда не захотите разрешить несколько списков для пользователя, но приятно знать, что это будет простое изменение! –

+0

Спасибо за все это Эндрю! Очень полезно. – hangloos

+0

Не стоит беспокоиться, я нахожу эту вещь действительно полезной версией, когда я некоторое время находился вне Rails/более интересных ассоциаций. –

0

Схема: Список

user_id 
review_id 

Это означает, что ваш список принадлежит к одному пользователю, а также принадлежит к одному обзору ... но вы определили список ваших ассоциаций как это:

belongs_to :user 
has_many :reviews 

так рельсы путаются, почему список имеет review_id (который является belongs_to ассоциации вещи). и смотрит на модель обзора, надеясь, что у нее будет столбец list_id ... потому что именно так вы решили бы этот ... и все же ваша модель обзора имеет много списков, поэтому она не может решить проблему.

Не могли бы вы рассказать нам, что вам на самом деле нужно? Как это должно быть связано? следует ли изменить ассоциации, которые вы определили, для соответствия столбцам id или можете ли вы более подробно указать отношения между моделями (например, с диаграммой объектов), а затем мы можем рассказать вам, как изменить свои идентификаторы-столбцы/ассоциации в соответствии с вашими объектно-схема?

+0

Хорошо, что часть путаницы имеет смысл. Я пытаюсь дать пользователю список, который может иметь как можно больше обзоров. – hangloos

+0

Кроме того, отзыв может быть представлен в нескольких списках пользователей. – hangloos

0

Для этого вам необходимо использовать has_and_belongs_to_many. Взгляните на http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association.

Проблема заключается в том, что ваша модель списка has_many обзоров и ваша модель обзора has_many перечислены. Если две модели имеют отношение has_many друг к другу, как вы можете моделировать это в базе данных? То есть, где бы вы поместили внешний ключ? В зависимости от того, какая таблица имеет внешний ключ, может быть только отношение принадлежность к другой таблице. то есть он может принадлежать только один запись другой таблицы.

Решение этого вопроса - использовать таблицу соединений. В рельсах это обычно имеет название что-то вроде lists_reviews. В этой таблице объединений будут два внешних ключа: один для таблицы списков и один для отзывов. Таким образом, каждая таблица может иметь отношение has_many к другому. В рельсах вы можете использовать has_and_belongs_to_many. Проверьте ссылку выше для получения дополнительной информации.

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