Я пытаюсь создать запись в рамках объединяющей таблицы от действия кнопки. Я имел бы модель событий и хотел бы отследить выбранные события от каждого пользователя.
Я использовал отношения HABTM, так как мне действительно не нужны никакие дополнительные поля.
User.rb:
has_to_and_belongs_to_many :events
Event.rb:
has_to_and_belongs_to_many :users
Миграция Events_Users:
[user_id, event_id, id=>false]
Я застреваю на фактическом создании записи. Кто-то помог мне ранее с включением записи в консоли:
u = User.find(1)
u.events << Event.find(1)
Теперь я хотел бы выполнить действие в результате щелчка на ссылку... Это находится в правильном направлении?
def add
@user = User.find(session[:user_id])
@event = Event.find(params[:id])
if @user.events.save(params[:user][:event])
flash[:notice] = 'Event was saved.'
end
end
Если я добавляю a @user.events.new
где-нибудь и раз так где я помещаю параметрические усилители который пользователь и который событие?
Следующий код должен работать (при условии, что вы передаете параметр с именем id, которое соответствует идентификатору объекта события):
def add
@user = User.find(session[:user_id])
@event = Event.find(params[:id])
@user.events << @event
flash[:notice] = 'Event was saved.'
end
Я вижу в вашем коде следующие проблемы:
Вы передаете хэш в .save. Сохранение должно принимать только логическое значение, соответствующее тому, должны ли выполняться проверки, и истинно по умолчанию. Однако .create и .new могут принимать хэш значений. (.save будет использоваться после .new).
Вы загружаете событие через params [: id], но затем пытаетесь создать событие через params [: user] [: event]. Что ты хочешь сделать? Создать или загрузить? (в моем примере предполагается загрузка)
Действия, которые имеют такой эффект, должны происходить, когда пользователь нажимает кнопку и отправляет форму, а не «щелкает ссылку». Этот код может быть уязвим для подделки межсайтовых запросов (кто-то может обманом заставить кого-то щелкнуть ссылку на другом сайте, на котором было выполнено это действие). Формы Rails, если они реализованы правильно, защищены от этого, потому что они используют токен защиты от подделки запросов.
Скорее всего, вы захотите перенаправить пользователя после этого действия. Отображение страниц после выполнения подобных действий (а не перенаправления) считается плохой практикой.
То, что вы делали в консоли, нужно делать в контроллере.
def add
@user = User.find(session[:user_id])
@event = Event.find(params[:id])
@user.events << @event
flash[:notice] = 'Event was saved.'
end
Здесь следует отметить, что оператор << для существующих записей вызывает немедленное сохранение ассоциации.
См. документацию ActiveRecord для получения дополнительной информации.
Если event_id передается как params [: id] и вы добавляете только одно событие в этот вызов, вы можете сделать следующее в коде вашего контроллера :
User.find(session[:user_id]).events << Event.find(params[:id])
flash[:notice] = 'Event was saved.'
Вам не нужно явное save
, чтобы сохранить ассоциацию has_many существующего экземпляра модели.
Сценарий 1
u = User.new(..)
u.events << Event.first
# Now you need to call `save` in order to save the user object
# and the events association
u.save
Сценарий 2
u = User.first
u.events << Event.first
# Don't need to call `save` on `u` OR `u.events`