【问题标题】:RoR 5 find_or_initialize_by in nested form on has_many relationship not savingRoR 5 find_or_initialize_by 在 has_many 关系上的嵌套形式未保存
【发布时间】:2016-12-09 04:36:30
【问题描述】:

我感觉我错过了一些明显的东西......

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

许多用户可以通过连接表Usergrants与许多Grants相关联

    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"}

我的缺点是什么?

【问题讨论】:

  • 您是否检查过发送的参数与实际接收的参数结构是否匹配?!
  • 日志结果已添加到帖子中。

标签: ruby-on-rails forms nested-forms ruby-on-rails-5 has-many-through


【解决方案1】:

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

首先,我错过了accepts_nested_attributes_for 电话。

其次,我必须将&lt;%= f.fields_for :usergrants %&gt;复数化

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

第四,我必须允许 users_params 中的 User.id,不知道为什么,但日志告诉我 ID 被拒绝与我的联接表有关。

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

Stuff 现在就像帮派克星一样运作。谢谢各位大侠指点!

【讨论】:

  • 根据 SO 再过 4 小时。
【解决方案2】:

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

accepts_nested_attriubtes_for :user_agents

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

编辑:

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

<%= f.fields_for :usergrants  %>

【讨论】:

  • 所以你是对的,我错过了这个(注意模型称为 Usergrants,长篇大论),但表单仍然没有捕获 Usergrants 的“初始化”记录。
  • 完成。我发现我现在正在处理的验证存在问题,可能就是这么简单(我必须从表单中删除 remote: true 才能看到错误)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多