在多对多关系中添加记录失败

时间:2016-04-13 13:22:27

标签: ruby ruby-on-rails-4 activerecord

我在Rails应用程序中有多对多连接,它看起来像这样:

class Workspace
  has_and_belongs_to_many :users, dependent: :destroy
end

class User
  has_and_belongs_to_many :workspaces
end

class UserWorkspace
  belongs_to :user
  belongs_to :workspace
end

架构:

create_table :users_workspaces do |t|
  t.integer :user_id
  t.integer :workspace_id
  t.integer :role, default: 0

  t.timestamps null: false
end

然后我想创建一个这样的新记录:

@user.workspaces.create(:workspace_id => @workspace.id, :role => 1)

或者

@user.workspaces << @workspace

并在日志中出错:

(0.0ms)  begin transaction
(0.0ms)  begin transaction
(0.1ms)  rollback transaction
(0.1ms)  rollback transaction
Completed 500 Internal Server Error in 207ms (ActiveRecord: 5.5ms)
Completed 500 Internal Server Error in 207ms (ActiveRecord: 5.5ms)

ActiveRecord::UnknownAttributeError (unknown attribute 'workspace_id' for Workspace.):
app/controllers/sessions_controller.rb:10:in `block in sign_up'
app/controllers/sessions_controller.rb:4:in `sign_up'

我做错了什么?

PS控制器:

def sign_up
respond_to do |format|
  @user = User.new(user_params)
  if @user.save
    @workspace = Workspace.new(title: "#{@user.name}'s workspace")
    @workspace.save
    puts "workspace id: #{@workspace.id}"
    @user.workspaces.create(:workspace_id => @workspace.id, :role => 1)
    puts "workspaces count: #{@user.workspaces.count}"
    @user.workspace = @workspace
    @user.update_attributes(user_params)

    flash.now[:success] = 'Welcome! Please check activation letter in your email box.'
    format.js { render 'signup_message' }
  else
    format.js { render 'render_signup_errors' }
  end
end
end

private

def user_params
  params.require(:user).permit(:email, :password, :password_confirmation, :name, :workspace_id)
end

1 个答案:

答案 0 :(得分:1)

您的代码存在一些问题。例如,您正在创建已创建的工作区(@user.workspaces.create),或允许未使用的:workspace_id等。

请见下面的代码:

def sign_up
  respond_to do |format|
    @user = User.new(user_params)
    if @user.save

      @workspace = Workspace.new(title: "#{@user.name}'s workspace")

      if @workspace.save
        # Like this
        UserWorkspace.create(user: @user, workspace: @workspace, role: 1)

        # Or, like this
        @user.user_workspaces.create!(workspace_id: @workspace.id, role: 1)
      end

      flash.now[:success] = 'Welcome! Please check activation letter in your email box.'
      format.js { render 'signup_message' }
    else
      format.js { render 'render_signup_errors' }
    end
  end
end

private

# You don't need :workspace_id since you are not using it anywhere
def user_params
  params.require(:user).permit(:email, :password, :password_confirmation, :name)
end