has_many :through add extra param in join table in one call (对象创建)

has_many :through add extra param in join table in one call (object creation)

我有以下代码,允许用户通过带有额外参数(创建者)的连接 table 创建新相册。

为此,我的控制器执行了 2 个请求(一个用于创建相册对象和协作对象/另一个用于使用额外参数更新协作对象)。

我想知道是否有一种方法可以只通过一个请求进行此调用。 (在创建相册的同时添加额外的"creator"参数)

谢谢。

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

views/albums/new

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

您可以只在新相册实例上添加关联对象:

@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 保存关联,但不是最佳选择,因为它会触发用户模型的不必要更新。