Почему этот связанный вызов create не работает? - PullRequest
1 голос
/ 06 февраля 2009

У меня есть модель User, в которой много предметов. Рейтинг принадлежит Пользователю и Предмету.

В БД я установил ratings.user_id не равным NULL.

когда я создаю Предмет, я хотел бы сделать это:

  def create
    current_user.items.create(params[:item]).ratings.create(params[:rating]
    redirect_to items_path
  end

Однако это приводит к ошибке SQL "user_id не может быть nil"

поэтому я переписал метод создания как

  def create
    current_user.items.create(params[:item]).ratings.create(params[:rating].merge({:user_id => current_user}))
    redirect_to items_path
  end 

, который отлично работает.

Тем не менее, я думал, что создание цепочки методов create из получателя текущего пользователя заполнит user_id рейтинга. Кто-нибудь знает, почему нет?

ТИА.

Ответы [ 3 ]

1 голос
/ 06 февраля 2009

Я бы порекомендовал вам нормализовать это, если это возможно, в базе данных. Может быть, вынуть атрибут user_id из таблицы рейтингов и, если вам нужно в вашей модели, получить его через объединение, используя метод: through

class Rating
    has_many :items
    has_one :user, :through=>:items
1 голос
/ 06 февраля 2009

Если вы создали и сохранили элемент, а затем сделали оценку из этого элемента, он не передал бы пользователя в рейтинг, верно? Вы бы просто назвали его @ rating.item.user, верно?

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

Заставьте меня задуматься, действительно ли вам нужны пользовательские отношения с оценками has_many.

0 голосов
/ 06 февраля 2009

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

...