Jam*_*ker 1 ruby database activerecord ruby-on-rails
所以我必须遵循模型.
class Team < ActiveRecord::Base
belongs_to :user
has_and_belongs_to_many :players
accepts_nested_attributes_for :players
end
class Player < ActiveRecord::Base
has_many :statistics
has_and_belongs_to_many :teams
end
Run Code Online (Sandbox Code Playgroud)
我希望建立一个拥有玩家的团队,这些团队将由用户选择.我可以通过以下方式在控制台中完美地完成此操作.
@user = User.find(10)
@team = @user.build_team(name: "MyTeam", points: 0)
#<Team team_id: nil, name: "MyTeam", points: 0, user_id: 10>
@team.players.build(name: "Messi")
#<Player player_id: nil, name: "Messi", role: nil>
@team.save
Run Code Online (Sandbox Code Playgroud)
然而,由于强大的参数,我真的很难通过参数.这是我的看法
<%= form_for :team do |f| %>
<%= f.label :name %><br />
<%= f.text_field :name %>
<%= f.fields_for :players do |players| %>
<%= players.label :player_name %>
<%= players.text_field :name %>
<% end %>
<div><%= f.submit "Create Team" %></div>
<% end %>
Run Code Online (Sandbox Code Playgroud)
我想使用团队参数和使用播放器参数的播放器来构建团队,但是我无法弄清楚如何在控制器中使用它.
class TeamController < ApplicationController
before_action :authenticate_user!
def new
end
def create
@user = User.find(current_user.id)
@team = @user.build_team(team_params) #Just the team paramaters
@team = @team.players.build(player_params)# I want just the player params
@team.save
end
private
# I can add the player param as nested i.e. .permit(:name, :players => [:name])
# but then build_team complains about receiving an array.
def team_params
params.require(:team).permit(:name)
end
end
Run Code Online (Sandbox Code Playgroud)
欢迎任何解决方案,以及任何改进.
编辑 - 增加的模式
create_table "players", primary_key: "player_id", force: true do |t|
t.string "name", limit: 50, null: false
t.string "role", limit: 30, null: false
end
create_table "players_teams", id: false, force: true do |t|
t.integer "player_id", null: false
t.integer "team_id", null: false
end
# players_teams is a Composite Primary Key, as instructed in the guides;
# also essential for targeting.
create_table "teams", primary_key: "team_id", force: true do |t|
t.string "name", limit: 200, null: false
t.integer "points", default: 0, null: false
t.integer "user_id", null: false
end
Run Code Online (Sandbox Code Playgroud)
编辑2
由于这还没有得到回答,我将添加更多关于我正在尝试的解释.
用户有一个团队,我可以建立团队,并且由于ActiveRecord也建立了关系.然后用户团队有很多玩家和玩家有很多团队,当我尝试建立这种关系时,玩家表永远不会改变,没有创建任何关系.
我觉得我应该再次强调以下功能在rails控制台中完美运行
@user = User.find(10)
@team = @user.build_team(name: "MyTeam", points: 0)
#<Team team_id: nil, name: "MyTeam", points: 0, user_id: 10>
@team.players.build(name: "Messi")
#<Player player_id: nil, name: "Messi", role: nil>
@team.save
Run Code Online (Sandbox Code Playgroud)
团队设置为接受嵌套参数,所以我认为这将工作.
@team = @user.build_team(team_params)
def team_params
params.require(:team).permit(:name, players_attributes: [:name, :role])
end
Run Code Online (Sandbox Code Playgroud)
我相信这应该建立玩家模型并创建关系,但是没有玩家被插入并且没有建立任何关系.
首先在TeamsController下面进行一些更改:
class TeamController < ApplicationController
before_action :authenticate_user!
def new
## Set "@team" and build "players"
@team = current_user.build_team
@team.players.build
end
def create
@team = current_user.build_team(team_params)
if @team.save
## Redirect to teams show page
redirect_to @team, notice: 'Team was successfully created.'
else
## In case of any error while saving the record, renders the new page again
render action: 'new'
end
end
private
# I can add the player param as nested i.e. .permit(:name, :players => [:name])
# but then build_team complains about receiving an array.
def team_params
## Permit players_attributes
params.require(:team).permit(:name, players_attributes: [:id, :name])
end
end
Run Code Online (Sandbox Code Playgroud)
在此之后,更新视图如下:
<%# Changed "form_for :team" to "form_for @team" %>
<%= form_for @team do |f| %>
<%= f.label :name %><br />
<%= f.text_field :name %>
<%= f.fields_for :players do |player| %> <%# Changed "|players|" to "|player|" %>
<%= player.label :name %> <%# Changed "player_name" to "name" and "players" to "player" %>
<%= player.text_field :name %> <%# Changed "players" to "player" %>
<% end %>
<div><%= f.submit "Create Team" %></div>
<% end %>
Run Code Online (Sandbox Code Playgroud)
设置一个实例变量@team,new并为此构建玩家@team.在视图代码中使用@team实例变量作为参数form_for.
我还建议在create动作中进行一些调整,以便了解团队是否得到了保存.并修复了team_params允许嵌套属性的方法players.
UPDATE
使用方法@team作为参数form_for是资源导向的风格和更喜欢的方式.阅读关于form_for用法的这个非常好的描述,以获得更好的想法.您仍然可以在使用时实现所需的代码,:team但这不是首选的方法.
示例使用:team:
<%= form_for :team do |f| %>
<%# ... %>
<%= f.fields_for :players, f.object.players.build do |player| %> <%# build the players for the team %>
<%# ... %>
<% end %>
<%# ... f.submit "Create Team" %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
fields_for在你的情况下将迭代@team.players属于特定团队(@team)的玩家().如果没有玩家那么你就不会在表单中看到玩家的任何字段,这就是为什么你建立玩家所以你至少得到一些空白字段供玩家输入,这就是为什么在使用时accepts_nested_attributes_for你需要建立嵌套属性.您可以在控制器级别(如上面建议的代码所示)或在表单内构建它们.
"在表单内"的示例:
<%= form_for @team do |f| %>
<%# ... %>
<%= f.fields_for :players, @team.players.build do |player| %> <%# build the players for @team %>
<%# ... %>
<% end %>
<%# ... f.submit "Create Team" %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6796 次 |
| 最近记录: |