使用自定义外键时,“无法写入未知属性”到HABTM连接表

时间:2016-03-23 04:46:08

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

用户可以通过HABTM游戏和游戏将HABTM用户视为故事讲述者,将他们与以后的关系区分开来,游戏将有许多用户作为参与者。

当我尝试通过Games控制器中的create方法将用户输入的User对象添加到@ game.storytellers时,Rails抛出错误“无法写入未知属性`user_id'”。

我很确定问题出在我上一次迁移中(在这篇文章的底部)。

models / user.rb

class User < ActiveRecord::Base
    has_and_belongs_to_many :games, association_foreign_key: "storyteller_id"
end

模型/ game.rb

class Game < ActiveRecord::Base
    has_and_belongs_to_many :storytellers, class_name: "User", 
                                           foreign_key: "storyteller_id"
    attr_accessor :storyteller_group
end

控制器/ games.rb

  def create
    @game = Game.new(game_params)
    @game.storytellers << params[:game][:storyteller_group].split(",").collect { |n| User.find_by(name: n) }

    respond_to do |format|
      if @game.save
        format.html { redirect_to @game, notice: 'Game was successfully created.' }
        format.json { render :show, status: :created, location: @game }
      else
        format.html { render :new }
        format.json { render json: @game.errors, status: :unprocessable_entity }
      end
    end
  end

视图/游戏/ _form.html.erb

<%= form_for(@game) do |f| %>
    [snip]

    <!-- Additional storytellers-->
    <div class="field">
        <%= f.label :storyteller_group, id: "create-game" %>
        <div class="input">
            <%= f.text_field :storyteller_group, value: current_user.name %>
        </div>
    </div>

    [snip]
<% end %>

分贝/迁移/ create_users.rb

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
      t.index :name

      t.string :email
      t.index :email

      [snip]

      t.timestamps
    end
  end
end

分贝/迁移/ create_games.rb

Class CreateGames < ActiveRecord::Migration
  def change
    create_table :games do |t|
      t.string :name
      t.text :description
      t.string :source

      t.timestamps
    end
  end
end

分贝/迁移/ games_users.rb

class GamesUsers < ActiveRecord::Migration
  def change
    create_table :games_users, id: false do |t|
      t.belongs_to :game, index: true
      t.integer :storyteller_id, index: true
    end
  end
end

1 个答案:

答案 0 :(得分:1)

您已经以相反的方式编写了HABTM外键定义。引自Rails guides

  

:association_foreign_key

     

按照惯例,Rails假定连接表中用于保存外键指向其他模型的列是添加了后缀_id的模型的名称。 :association_foreign_key选项允许您直接设置外键的名称。

  

:foreign_key

     

按照惯例,Rails假定用于保存指向此模型的外键的连接表中的列是添加了后缀_id的此模型的名称。 :foreign_key选项允许您直接设置外键的名称

因此,以下内容应该有效:

class User < ActiveRecord::Base
  has_and_belongs_to_many :games, foreign_key: "storyteller_id"
end

class Game < ActiveRecord::Base
  has_and_belongs_to_many :storytellers, class_name: "User", 
                                         association_foreign_key: "storyteller_id"
end