【问题标题】:Rails: "Validation failed: Class must exist" in a Form_withRails:Form_with 中的“验证失败:类必须存在”
【发布时间】:2021-12-14 01:35:32
【问题描述】:

我有一个名为 Order 的多重关系表,它属于一个 Relai(以避免单数/复数复杂化)、一个客户和一个组合。我使用下面提到的nested_attributes 相应地设置了我的订单模型。在添加客户部分之前,我想发送一封邮件,其中仅包含 @composition 和 @relai,并通过下拉菜单选择。

class Order < ApplicationRecord
  belongs_to :relai
  belongs_to :composition
  accepts_nested_attributes_for :relai
  accepts_nested_attributes_for :composition
end

我将 OrdersController 设置为从我的参数中获取 :composition_id

def new
    @order = Order.new
    @composition = Composition.find(params[:composition_id])
    @relais = Relai.all
  end

  def create
    @florist = Florist.first
    @composition = Composition.find(params[:composition_id])
    #@relai = Relai.find(params[:relai_id])  # If I add this line it returns "Couldn't find Relai without an ID"
    @order = Order.new(order_params)
    if @order.save!
      raise
      OrderMailer.order_mail(@order).deliver
      redirect_to thanks_purchase_path
    else
      render :new
    end
  end

  private

  def order_params
    params.require(:order).permit(
      florist_attributes: [:id],
      relai_attributes: [:id, :name, :address],
      composition_attributes: [:id, :name]
      )
  end

我的观点:

  <%= form_with(model: @order, url: composition_orders_path(@composition), local: true) do |compo| %>
    <%= compo.collection_select :relai, @relais, :id, :name %>
    <%= compo.fields_for :composition do |fc| %>
      <%= fc.collection_select :composition, @compositions, :id, :name %>
    <% end %>
    # Start Block that doesn't display the Relai.all
    #<%#= compo.fields_for :relai do |fr| %>
     #<%#= fr.label :relai, 'Ici la liste des relais :' %>
     #<%#= fr.association :relai, collection: @relais %>
     #<%#= fr.association :relai, @relais, :id, :name %>
    #<%# end %>
    # End Block
    <%= compo.submit "MAIL", class: "app-form-button" %>
  <% end %>

还有路线:

resources :compositions, only: [:show, :index] do
    resources :orders, only: [:show, :new, :create, :index]
  end

我也试过了:

有人能解释一下为什么我得到“验证失败:Relai 必须存在,Composition 必须存在”而这些出现在我的参数中吗?

{"authenticity_token"=>"[FILTERED]", "order"=>{"relai"=>"2"}, "commit"=>"MAIL", "composition_id"=>"3"}

我在 Rails 6.1.4 上;红宝石 2.6.6

【问题讨论】:

    标签: ruby-on-rails class validation activerecord form-with


    【解决方案1】:

    accepts_nested_attributes_for 可以从父母到孩子。您在子端使用它 (Order)。

    如果您只需要将现有的RelaiComposition 分配给Order,只需对它们都使用一个选择:

    class Order < ApplicationRecord
      belongs_to :relai
      belongs_to :composition
    end
    
      def new
        @order = Order.new
        @compositions = Composition.all
        @relais = Relai.all
      end
    
      def create
        @order = Order.new(order_params)
        if @order.save!
          OrderMailer.order_mail(@order).deliver
          redirect_to thanks_purchase_path
        else
          render :new
        end
      end
    
      private
    
      def order_params
        params.require(:order).permit(:relai_id, :composition_id)
      end  
    
    <%= form_with(model: @order, url: composition_orders_path(@composition), local: true) do |compo| %>
        <%= compo.collection_select :relai_id, @relais, :id, :name %>
        <%= compo.collection_select :composition_id, @compositions, :id, :name %>
        <%= compo.submit "MAIL", class: "app-form-button" %>
    <% end %>
    

    编辑:在控制器上设置合成。

      def new
        composition = Composition.find(params[:composition_id])
        @order = Order.new(composition: composition)    
        @relais = Relai.all
      end
    
      def create
        @order = Order.new(order_params)
        if @order.save!
          OrderMailer.order_mail(@order).deliver
          redirect_to thanks_purchase_path
        else
          render :new
        end
      end
    
      private
    
      def order_params
        params.require(:order).permit(:relai_id, :composition_id)
      end  
    
    <%= form_with(model: @order, url: composition_orders_path(@composition), local: true) do |compo| %>
        <%= compo.collection_select :relai_id, @relais, :id, :name %>
        <%= compo.hidden_field :composition_id %>
        <%= compo.submit "MAIL", class: "app-form-button" %>
    <% end %>
    

    【讨论】:

    • 感谢您的回答。事实上,我在孩子身上设置了accepts_nested_attributes_for。多么愚蠢的举动。我将所有accepts_nested_attributes_for 放在父母(Relai;作文;客户)上,针对订单。它猜它有效,因为我遇到了另一个错误。它返回给我undefined method save!对于 nil:NilClass`,我的参数设置正确! {"authenticity_token"=&gt;"[FILTERED]", "order"=&gt;{"relai_id"=&gt;"2"}, "commit"=&gt;"MAIL", "composition_id"=&gt;"1"}。我删除了&lt;%= compo.collection_select :composition_id, @compositions, :id, :name %&gt; 部分,因为@composition 在url 中设置。
    • Nvm 我在 OrdersController 的创建中忘记了 @order = Order.new(order_params)。现在 relai_id 很好,但只有当我输入 &lt;%= compo.collection_select :composition_id, @compositions, :id, :name %&gt; 时它才有效。我只需要一种从 url 而不是从 collection.select 中获取 :composition_id 的方法。
    • &lt;%= compo.collection_select :composition_id, @compositions, :id, :name, {selected: @composition.id}, {class: "no-display"} %&gt; 有效。否则他会给我一个错误。不能使用&lt;% 标签。感谢您的帮助@CAmador
    • @JoCoz 请看我的编辑。
    • 好的,它工作。我有最后一个问题,除了提交时,一切似乎都运行良好。我收到了邮件,但信息来自种子而不是表格。它为我保留了种子的价格和大小的基本信息,我只从表格中选择了继电器。有什么想法吗?
    猜你喜欢
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 2020-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多