Rails - Добавить запись в таблицу соединений с контроллера - PullRequest
9 голосов
/ 06 марта 2010

Я пытаюсь создать запись в таблице соединений из-за действия кнопки.Я хотел бы иметь модель событий и хотел бы отслеживать выбранные события от каждого пользователя.

Я использовал отношение 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

Должен ли я где-то добавить @user.events.new и, если да, куда я могу указать параметры какого пользователя и какое событие?

Ответы [ 3 ]

13 голосов
/ 06 марта 2010

Следующий код должен работать (при условии, что вы передаете параметр с идентификатором имени, который соответствует идентификатору объекта события):

   def add
     @user = User.find(session[:user_id])
     @event = Event.find(params[:id])
     @user.events << @event
     flash[:notice] = 'Event was saved.'
   end

Проблемы, которые я вижу в вашем коде:

  1. Вы передаете хеш в .save. Save должен принимать только логическое значение, соответствующее тому, следует ли запускать проверки, и по умолчанию имеет значение true. Однако .create и .new могут принимать хэш значений. (.save будет использоваться после .new).

  2. Вы загружаете событие через params [: id], но затем вы пытаетесь создать событие через params [: user] [: event]. Что вы хотите сделать? Создать или загрузить? (мой пример предполагает загрузку)

  3. Действия, которые имеют такой эффект, должны происходить, когда пользователь нажимает кнопку и отправляет форму, а не «щелкает ссылку». Этот код может быть уязвим для подделки межсайтовых запросов (кто-то может обмануть кого-то, чтобы он нажал на ссылку на другом сайте, на котором выполнялось это действие) Формы Rails, если они правильно реализованы, защищены от этого, поскольку они используют маркер защиты от подделки запросов.

  4. Скорее всего, вы хотите перенаправить пользователя после этого действия. Рендеринг страниц после выполнения таких действий (а не перенаправления) считается плохой практикой.

3 голосов
/ 06 марта 2010

Что вы сделали в консоли, вам нужно сделать в контроллере.

def add
  @user = User.find(session[:user_id])
  @event = Event.find(params[:id])
  @user.events << @event
  flash[:notice] = 'Event was saved.'
end

Здесь следует отметить, что оператор << для существующих записей приведет к немедленному сохранению ассоциации. </p>

Для получения дополнительной информации см. документацию ActiveRecord .

0 голосов
/ 06 марта 2010

Если 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`
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...