ruby-on-rails – 使用强参数Rails创建和更新嵌套模型
这是我的3个型号.
User has_many :memberships has_many :teams,through: :memberships,dependent: :destroy accepts_nested_attributes_for :memberships Team has_many :memberships has_many :users,dependent: :destroy accepts_nested_attributes_for :memberships Membership belongs_to :team belongs_to :user 以下是我的Team控制器的一些部分.我的目标是向某个团队添加/更新成员.请注意,添加成员的源已作为一组用户存在. TeamsController def create @team = Team.new(team_params) @team.users << User.find(member_ids) #add leader and members to team if @team.save #redirect to created team else #show errors end end def update #TO DO: update team roster here if @team.update(team_params) #redirect to updated team else #show errors end end Team控制器的强参数 #parameters for team details def team_params params.require(:team).permit(:name,:department) end #parameters for members (includes leader) def members_params params.require(:team).permit(:leader,members:[]) end #get id values from members_params and store in an array def member_ids members_params.values.flatten end 对于表单,我只有: >名称(文本字段) 我可以成功创建一个团队,同时在我的创建上传递验证(包括团队和成员模型).但是,我不知道如何更新团队,因为如果我使用@ team.users.clear然后简单地从create做同样的事情(我知道,这样做有点愚蠢),它会验证,但是无论是否有错误,它都会保存它. 表格代码 <%= form_for(@team,remote: true) do |f| %> <%= f.label :name,"Name" %> <%= f.text_field :name %> <%= f.label :department,"Department" %> <%= f.select :department,options_for_select(["Architectural","Interior Design"],department),include_blank: true %> <%= f.label :leader,"Leader" %> <%= f.select :leader,select_leaders(department,@team.id),{include_blank: true,selected: pre_select(:leader)} %> <%= f.label :members,"Members" %> <%= f.select :members,select_members(department,{include_blank: true},{id: "team_members",multiple: :multiple,data: {member_ids: pre_select(:members)}}%> <% end %> 表格注意事项: >此表单适用于空白和填充表单. 所以我的问题是: >我如何更新团队成员?是否可以根据我目前的强参数进行更新,还是需要修改? 一些选择导致解决方案 选项#1(迄今为止的最佳解决方案) 我只为此做了一个急救解决方案,所以我认为有一个比我下面做的更好的方法.我在这里做的是创建用户参数,其中使用从member_ids中找到的用户作为值. TeamsController def create team = Team.new(team_params.merge({users: User.find(member_ids)})) ... end def update ... if @team.update(team_params.merge({users: User.find(member_ids)})) .. end 选项#2 独立于解决方案1,我只有team_params作为强参数. TeamsController ... private def team_params params.require(:team).permit(:name,:department,:leader,members:[]) end 我为领导者和成员创建了setter方法.但似乎成员覆盖了领导者setter,因为我对两个setter使用了update方法,并且更新使用了与用户相同的资源.使用此选项似乎可以解决方法. Team ... def leader=(leader_id) #self.update(users: User.find(leader_id)) end def members=(members_ids) #self.update(users: User.find(members_id)) end 解决方法
因为,领导者和成员在你的场景中并没有那么不同.您可以将模型和视图表单更改为以下内容:
class Team < ActiveRecord::Base has_many :memberships has_many :users,dependent: :destroy accepts_nested_attributes_for :memberships end class User < ActiveRecord::Base has_many :memberships has_many :teams,dependent: :destroy end class Membership < ActiveRecord::Base belongs_to :team belongs_to :user accepts_nested_attributes_for :user end 并形成视图代码: <%= form_for(@team) do |f| %> <% if @team.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@team.errors.count,"error") %> prohibited this team from being saved:</h2> <ul> <% @team.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> <div class="field"> <%= f.label :name %><br> <%= f.text_field :name %> </div> <%= f.fields_for :memberships do |m| %> <div class="field"> <%= m.label :memberships_name %><br> <%= m.text_field :name %> </div> <%= m.fields_for :user do |u| %> <div class="field"> <%= u.label :user_name %><br> <%= u.text_field :name %> </div> <% end %> <% end %> <div class="actions"> <%= f.submit %> </div> <% end %> 此外,请确保您在控制器中更改此设置: # GET /teams/new def new @team = Team.new 3.times do # number of members you need to generate! @team.memberships.build{ |m| m.build_user } end end # GET /teams/1/edit def edit end # POST /teams # POST /teams.json def create @team = Team.new(team_params) respond_to do |format| if @team.save format.html { redirect_to @team,notice: 'Team was successfully created.' } format.json { render action: 'show',status: :created,location: @team } else format.html { render action: 'new' } format.json { render json: @team.errors,status: :unprocessable_entity } end end end private # Use callbacks to share common setup or constraints between actions. def set_team @team = Team.find(params[:id]) end # Never trust parameters from the scary internet,only allow the white list through. def team_params params.require(:team).permit(:name,memberships_attributes: [:id,:name,user_attributes: [:id,:name]]) end 虽然您可以在Rails控制台中执行此操作以执行快速代码验证: team_params = {"name"=>"Team","memberships_attributes"=>{"0"=>{"name"=>"Membership 1","user_attributes"=>{"name"=>"User 1"}},"1"=>{"name"=>"Membership 2","user_attributes"=>{"name"=>"User 2"}},"2"=>{"name"=>"Membership 3","user_attributes"=>{"name"=>"User 3"}}}} team = Team.new(team_params) team.save team.users #=> #<ActiveRecord::Associations::CollectionProxy [#<User id: 1,name: "User 1",email: nil,created_at: "2014-09-04 11:25:48",updated_at: "2014-09-04 11:25:48">,#<User id: 2,name: "User 2",#<User id: 3,name: "User 3",updated_at: "2014-09-04 11:25:48">]> 我希望它有所帮助. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |