A User can HABTM Games and a Game can HABTM Users as Storytellers, to differentiate them from a later relationship where a Game will have many Users as Participants.
Rails throws the error "can't write unknown attribute `user_id'" when I attempt to add the user-input User objects to @game.storytellers via the create method in the Games controller.
I'm pretty sure the problem lies in my last migration (at the bottom of this post).
models/user.rb
class User < ActiveRecord::Base
has_and_belongs_to_many :games, association_foreign_key: "storyteller_id"
end
models/game.rb
class Game < ActiveRecord::Base
has_and_belongs_to_many :storytellers, class_name: "User",
foreign_key: "storyteller_id"
attr_accessor :storyteller_group
end
controllers/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
views/games/_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 %>
db/migrations/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
db/migrations/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
db/migrations/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
You have written your HABTM foreign keys definitions in just the opposite way. Quoting from Rails guides :
:association_foreign_key
By convention, Rails assumes that the column in the join table used to hold the foreign key pointing to the other model is the name of that model with the suffix _id added. The :association_foreign_key option lets you set the name of the foreign key directly.
and
:foreign_key
By convention, Rails assumes that the column in the join table used to hold the foreign key pointing to this model is the name of this model with the suffix _id added. The :foreign_key option lets you set the name of the foreign key directly
So, the following should work:
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.