has_many: через добавление дополнительного параметра в таблицу соединений за один вызов (создание объекта) - PullRequest
0 голосов
/ 30 октября 2018

У меня есть следующий код, позволяющий пользователю создавать новый альбом с помощью таблицы соединений с дополнительными параметрами (создатель).

Для этого мой контроллер выполняет 2 запроса (один для создания объекта альбома и объекта сотрудничества / другой для обновления объекта сотрудничества дополнительными параметрами).

Я хотел бы знать, есть ли способ сделать этот звонок только с одним запросом. (добавить дополнительные параметры «создатель» в то же время, что и создание альбома)

Спасибо.

albums_controller.rb

class AlbumsController < ApplicationController

  def new
    @album = current_user.albums.build
  end

  def create
    @album = current_user.albums.build(album_params)
    if current_user.save
      @album.collaborations.first.update_attribute :creator, true
      redirect_to user_albums_path(current_user), notice: "Saved."
    else
      render :new
    end
  end

  private

    def album_params
      params.require(:album).permit(:name)
    end

end

Album.rb

class Album < ApplicationRecord

  # Relations
  has_many :collaborations
  has_many :users, through: :collaborations

end

Collaboration.rb

class Collaboration < ApplicationRecord
  belongs_to :album
  belongs_to :user
end

User.rb

class User < ApplicationRecord
  has_many :collaborations
  has_many :albums, through: :collaborations
end

просмотр / альбомы / новый

= simple_form_for [:user, @album] do |f|
  = f.input :name
  = f.button :submit

1 Ответ

0 голосов
/ 30 октября 2018

Вы можете просто добавить связанные объекты в новый экземпляр альбома:

@album = current_user.albums.new(album_params)
@album.collaborations.new(user: current_user, creator: true)

При вызове @album.save ActiveRecord автоматически сохранит связанные записи в той же транзакции.

class AlbumsController < ApplicationController

  def new
    @album = current_user.albums.new
  end

  def create
    @album = current_user.albums.new(album_params)
    @album.collaborations.new(user: current_user, creator: true)
    if @album.save
      redirect_to user_albums_path(current_user), notice: "Saved."
    else
      render :new
    end
  end

  private

    def album_params
      params.require(:album).permit(:name)
    end
end

Вы также звоните current_user.save, а не @album.save. Первый действительно работает из-за того, что он заставляет AR сохранять ассоциации, но не является оптимальным, так как он запускает бесполезное обновление пользовательской модели.

...