RoR 5 find_or_initialize_by 嵌套形式 has_many 关系未保存

RoR 5 find_or_initialize_by in nested form on has_many relationship not saving

我觉得我遗漏了一些明显的东西...

Usergrant 记录未通过表单 (User#update) 保存或更新。

许多用户可以通过加入 table Usergrants

与许多授权相关联
    class User < ActiveRecord::Base
      has_many :usergrants
      has_many :grants, through: :usergrants
      accepts_nested_attributes_for :usergrants, allow_destroy: true


    class Grant < ApplicationRecord
      validates_presence_of :name
      has_many :usergrants
      has_many :users, through: :usergrants
    end


    class Usergrant < ApplicationRecord
      belongs_to :user
      belongs_to :grant
      validates :user_id, :grant_id, :active, :percent, presence: true
    end

控制器(具有强参数):

def edit
  @title = "Edit User"

  @user = User.find(params[:id])
  @grants = Grant.all.where(active: true)

  if current_user == @user
    @page_title = "Edit your profile"
  else
    @page_title = "Edit "+@user.fname+"\'s profile"
  end

  if current_user.can_approve_this?(@user)
    @disabled = false
    @readonly_shower = "readonly-shower"
  else
    @disabled = true
    @readonly_shower = ""
  end

  @active_def = @user.active
  @salary_def = @user.pay_type
  @super_array = super_array
  @dept_array = dept_array
  @pw_lang = "Change password"
  session[:return_url] = back_uri

  if @user.pay_type == "Salary"
    @salary_hider = ""
    @hourly_hider = "hidden"
  else
    @salary_hider = "hidden"
    @hourly_hider = ""
  end
end

def update
  @user = User.find(params[:id])
  @grants = Grant.all.where(active: true)

  @user.salary_rate == 0.0 if @user.salary_rate.nil?
  @user.hourly_rate == 0.0 if @user.hourly_rate.nil?

  if @user.update_attributes(user_params)
    flash[:success] = "Profile updated"
    redirect_to session[:return_url]
  else
    @dept_array = dept_array
    @super_array = super_array
    render 'edit'
  end
end

def user_params
  params.require(:user).permit(
    :id, :fname, :lname, :active,
    ...
    :usergrants_attributes => [:id, :user_id, :grant_id, :active, :percent])
end

以及用户表单:

<%= form_for( @user, remote: true) do |f| %>
...
  <% @grants.each do |grant| %>
    <%= f.fields_for :usergrant, @user.usergrants.find_or_initialize_by(user: @user, grant: grant) do |ug| %>
    ...
      <%= grant.name %>
      <%= ug.text_field :user_id, value: user.id %>
      <%= ug.text_field :grant_id, value: grant.id %>
      <%= ug.text_field :active %>
      <%= ug.text_field :percent %>
    <% end %>
  <% end %>
...
<% end %>

我可以在控制台中创建 Usergrant 记录,它们会按预期显示在表单中。 User.usergrantGrant.usergrant 的表现符合预期。

这是日志:

    Parameters: {"utf8"=>"✓", "authenticity_token"=>"...", "user"=>{"id"=>"1", 
"fname"=>"Chip", "lname"=>"...", "email"=>"...", "time_zone"=>"Eastern Time (US & 
Canada)", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", 
"usergrants_attributes"=>{"0"=>{"id"=>"2", "user_id"=>"1", "grant_id"=>"1", "active"=>"0", 
"percent"=>"0.0"}, "1"=>{"id"=>"1", "user_id"=>"1", "grant_id"=>"4", "active"=>"1", 
"percent"=>"25.0"}, "2"=>{"id"=>"3", "user_id"=>"1", "grant_id"=>"5", "active"=>"0", 
"percent"=>"0.0"}}}, "id"=>"1"}

我的缺点是什么?

由于一个用户有多个UserAgent对象,所以需要在User模型中写accepts_nested_attributes_for

accepts_nested_attriubtes_for :user_agents

只有这样,您才能为给定用户创建或修改现有 UserAgent 对象。

编辑:

您正在做的另一件事是:<%= f.fields_for :usergrant。由于 User 模型有很多 Usergrants,所以这里必须是复数,如下所示:

<%= f.fields_for :usergrants  %>

好吧,在@Arslan_Ali和@crazy_vine的帮助下,我克服了这个问题。

首先,我错过了 accepts_nested_attributes_for 电话。

其次,我不得不复数<%= f.fields_for :usergrants %>

第三,我意识到我可以简化这个:<%= f.fields_for :usergrant, @user.usergrants.find_or_initialize_by(grant: grant) do |ug| %>(摆脱了 user: @user

第四,我不得不在 users_params 中允许 User.id,不知道为什么,但日志告诉我 ID 在我加入 table 时被拒绝了。

第五,我有一些我看不到的表单错误,因为我的顶级表单设置为 remote: true,删除它显示 Usergrant.activeUsergrant.percent 正在抛出错误。我调整了我的验证并为我的列添加了默认值。

现在事情就像帮派克星一样运作。谢谢大家的指导!