【问题标题】:Rails model validation on form with new parent and child带有新父子的表单上的 Rails 模型验证
【发布时间】:2023-03-22 03:00:01
【问题描述】:

我是 Rails 新手,但现在想知道,当我在表单中尝试同时创建子对象和父对象时,Rails 验证是否会丢失在模型对象上?

在我的示例中(模型以粗体显示) 1 - Cake - has_many - CakeDetails

许多 - CakeDetails - 属于 1 - 大小

1 - CakeType - 属于_to 1 - Cake

我已经创建了一个表单,它允许我创建一个蛋糕,指定尺寸、相关价格以及蛋糕的类型。

但似乎所有内置的模型验证都消失了。

这是正确的吗?如何将验证带回我的模型对象?

当我呈现新操作时,我会打开一个空白表单,当我提交一个空白表单时,我会得到以下信息:

Started POST "/cakes" for 127.0.0.1 at 2018-04-25 21:19:03 +0100
Processing by CakesController#create as JS
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"r6B2ult7w7z4vez95f2pNXmk7Q1rYSzj8Wi9VwnS4EgIAw8PG/w7isfAeiiSB9sY8+0+oHldMVpy1GFKBmrpmw==", "cake"=>{"name"=>"", "description"=>"", "cake_type_id"=>"", "cake_details_attributes"=>{"0"=>{"_destroy"=>"true", "price"=>""}, "1"=>{"_destroy"=>"true", "price"=>""}}}, "commit"=>"Create Cake"}
   (0.1ms)  begin transaction
   (0.1ms)  rollback transaction
  Rendering cakes/new.html.erb within layouts/application
  CakeType Load (0.3ms)  SELECT "cake_types".* FROM "cake_types"
  Rendered cakes/_form.html.erb (15.9ms)
  Rendered cakes/new.html.erb within layouts/application (19.6ms)
Completed 200 OK in 109ms (Views: 100.4ms | ActiveRecord: 0.5ms)

我知道它回滚交易是因为没有 cake_type_id。但是没有显示错误。

以下是我的表单中的错误显示部分。 我尝试添加更多内容来检查嵌套对象中的错误,但没有看到任何内容。

  <% if @cake.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(cake.errors.count, "error") %> prohibited this cake from being saved:</h2>
      <ul>
      <% @cake.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>
  <% @cake.cake_details.each do |detail| %>
    <% if detail.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(cake.errors.count, "error") %> prohibited this cake from being saved:</h2>
      <ul>
      <% @cake.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
    <% end %>
  <% end %>

我的蛋糕模型

class Cake < ApplicationRecord
  validates :name, :description, :cake_type, presence: true

  belongs_to :cake_type
  has_many :cake_details, -> {order('size_id ASC')}, inverse_of: :cake
  has_many :sizes, through: :cake_details
  accepts_nested_attributes_for :cake_details, :allow_destroy => true

  validates_associated  :cake_type, :cake_details
end

蛋糕控制器

  def create
    #@cake = Cake.new(params[cake:{}])
    #params.require(:cake).permit(:name, :description,:cake_type_id)

    @cake = Cake.new(cake_params)
    respond_to do |format|
      if @cake.save
        format.html { redirect_to @cake, notice: 'Cake was successfully created.' }
        format.json { render :show, status: :created, location: @cake }
      else
        format.html { render :new }
        format.json { render json: @cake.errors, status: :unprocessable_entity }
      end
    end
  end

def cake_only_params
  params.require(:cake).permit(:name, :description,:cake_type_id)
end

def cake_params
  params.require(:cake).permit(:name, :description,:cake_type_id, cake_type_id:[:type_id],
  cake_details_attributes:[:_destroy, :id, :cake_id, :size_id, :price])
end

更新

我认为我必须访问我在操作中声明的变量,例如 @cake 但我更新了我的表单以使用它

<%= form_with(model: cake, local: true) do |form| %>

而不是我认为我需要它的方式:

<%= form_with(model: @cake) do |form| %>

我会阅读文档,但任何关于我为什么搞砸这个问题的 cmets 都非常感谢。刚开始学习这个框架...:/

【问题讨论】:

  • “......似乎所有内置模型验证都消失了”是什么意思?你的“问题”是如何以及在哪里表现出来的?
  • 添加了更多细节-希望上面有足够的信息。我可以看到事务未提交,但在提交空表单时我没有看到页面上显示错误
  • Welp,我想您不妨向我们展示您的CakesController.create 的样子。顺便说一句,error_explanation div 是否显示在您的页面上? (PS,看起来你最终会得到多个divsid='error_explanation'。这不好。)
  • 添加了更多细节!是的 - 只是想看看任何有效的东西!我没有看到任何 div :( 添加了我正在玩的参数。是否可以只创建蛋糕,然后创建子记录以强制验证?
  • 知道了...我不得不更改表格的顶部 - 我会用我的方式和现在的情况更新答案:/感谢您这么快回复!跨度>

标签: ruby-on-rails validation activerecord model nested-form-for


【解决方案1】:

根据this article,我敢肯定,在Rails 5 的其他地方,所有使用form_with 创建的表单默认都是远程的(即,以js 提交)。

通过将local: true 添加到form_with,您强制表单以html 提交,然后您的控制器使用format.html

【讨论】:

    【解决方案2】:

    我认为我必须访问我在操作中声明的变量,例如

    @蛋糕

    但我更新了我的表单以使用它:

    <%= form_with(model: cake, local: true) do |form| %>
    

    而不是我认为我需要它的方式:

    <%= form_with(model: @cake) do |form| %>
    

    现在可以了。

    特别感谢 jvillian 如此迅速的响应。

    并注意到:

    通过将local: true 添加到form_with,您强制表单以html 提交,然后您的控制器使用format.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多