Ruby on rails 在多对多关系中连接两个模型
我有个问题。 我想在我的球员身上找到所有的比赛,显示球员的位置。所以我建立了一种多对多的关系 匹配模型:Ruby on rails 在多对多关系中连接两个模型,ruby-on-rails,ruby,ruby-on-rails-4,activerecord,Ruby On Rails,Ruby,Ruby On Rails 4,Activerecord,我有个问题。 我想在我的球员身上找到所有的比赛,显示球员的位置。所以我建立了一种多对多的关系 匹配模型: class Match < ActiveRecord::Base has_many :match_schedules has_many :players, through: :match_schedules end 工作正常,我可以用名称显示循环: <% @player.matches.each do |match| %> <%= match.playerA
class Match < ActiveRecord::Base
has_many :match_schedules
has_many :players, through: :match_schedules
end
工作正常,我可以用名称显示循环:
<% @player.matches.each do |match| %>
<%= match.playerA %>
<% end %>
及(表格):
<div class="form-inputs">
<%= f.select :playerA, options_for_select(player_hash(@abc)) %>
<%= f.select :playerB, options_for_select(player_hash(@abc)) %>
<%= f.input :PlayerApoints %>
<%= f.input :PlayerBpoints %>
</div>
和my schema.rb:
ActiveRecord::Schema.define(version: 20150706185030) do
create_table "match_schedules", force: :cascade do |t|
t.integer "match_id"
t.integer "player_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "matches", force: :cascade do |t|
t.string "playerA"
t.string "playerB"
t.integer "PlayerApoints"
t.integer "PlayerBpoints"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "players", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "avatar_file_name"
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
end
您遗漏了match_params散列,因此我不得不做一些猜测,但大致如下: 在你的比赛课上:
class Match < ActiveRecord::Base
has_many :match_schedules
has_many :players, through: :match_schedules
accepts_nested_attributes_for :match_schedules
end
在match_params白名单中,您需要添加:
..., :player_ids => [])
因为它是一个数组,所以需要将它放在其他参数之后
您还必须修改视图代码。基本上,您希望返回一个match\u schedules\u attributes=>{player\u ID=>[1,2]}
这使您能够告诉MatchSchedule
表与该match\u ID
关联的每个玩家的ID。您可以在块的表单中使用的字段。看到这个了吗
因此,在比赛控制器的
创建
操作中,它还应该在比赛时间表表中保存两条记录,一条记录有每个球员的id和该比赛的id。你有一个单独的比赛和比赛时间表表,这真的需要吗?如果是这样的话,你不应该在你的比赛日程中有一个球员id,而应该只有一个比赛id。或者反过来说,你应该在比赛表中有分数,在比赛日程表中每一场比赛都有两个条目,标识每个球员。您需要对表进行规范化,以删除冗余数据并使关系更清晰。的字段\u实际上是这里的关键。我将添加一个hidden_字段
,其中包含比赛id,该字段将与球员id关联。你能给我一个例子吗?我做了这样的事情:在我的SQLite数据库浏览器中,我看不到我的match_schedules表中的任何数据。顺便说一句,使用你的match model修复程序,我甚至无法在rails控制台中为玩家添加匹配项。不可能在注释中读取那么大的代码。请更新您的问题。我没有计算出我答案中的每一个细节,主要是因为我没有可以测试任何东西的工作副本。如果你想让我更具体一点,我必须有一个可以克隆和使用的存储库。正如我上面所说的,你真的需要在你的表单中为循环使用字段。如果您不了解如何为
使用fields\u,您将无法使用嵌套参数编写更复杂的表单。我不明白为什么为
添加接受嵌套的属性会破坏匹配模型。如果删除该选项,代码是否再次工作?
<div class="form-inputs">
<%= f.select :playerA, options_for_select(player_hash(@abc)) %>
<%= f.select :playerB, options_for_select(player_hash(@abc)) %>
<%= f.input :PlayerApoints %>
<%= f.input :PlayerBpoints %>
</div>
def new
@match = Match.new
@abc = Player.all
end
def create
@match = Match.new(match_params)
respond_to do |format|
if @match.save
format.html { redirect_to @match, notice: 'Match was successfully created.' }
format.json { render :show, status: :created, location: @match }
else
format.html { render :new }
format.json { render json: @match.errors, status: :unprocessable_entity }
end
end
end
ActiveRecord::Schema.define(version: 20150706185030) do
create_table "match_schedules", force: :cascade do |t|
t.integer "match_id"
t.integer "player_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "matches", force: :cascade do |t|
t.string "playerA"
t.string "playerB"
t.integer "PlayerApoints"
t.integer "PlayerBpoints"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "players", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "avatar_file_name"
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
end
class Match < ActiveRecord::Base
has_many :match_schedules
has_many :players, through: :match_schedules
accepts_nested_attributes_for :match_schedules
end
def new
@match = Match.new
@match.match_schedules.build
@abc = Player.all
end
def create
@match = Match.new(match_params)
respond_to do |format|
if @match.save
format.html { redirect_to @match, notice: 'Match was successfully created.' }
format.json { render :show, status: :created, location: @match }
else
format.html { render :new }
format.json { render json: @match.errors, status: :unprocessable_entity }
end
end
end
..., :player_ids => [])