简体   繁体   English

Rails属于具有accept_nested_attributes_for的多个模型

[英]Rails belongs_to multiple models with accept_nested_attributes_for

I'm building an invoice system for a car trader where each invoice is linked to one customer and one vehicle, with customers potentially having many invoices and vehicles also having many invoices. 我正在为汽车贸易商构建一个发票系统,其中每张发票都链接到一个客户和一辆车,客户可能有很多发票,而车辆也有很多发票。 I have got it working with one nested model doing the following: 我已经使用一个嵌套模型执行以下操作:

purchase_invoice.rb Purchase_invoice.rb

class PurchaseInvoice < ApplicationRecord
  belongs_to :vehicle
  accepts_nested_attributes_for :vehicle
end

vehicle.rb vehicle.rb

class Vehicle < ApplicationRecord
  has_many :purchase_invoices
end

purchase_invoices_controller.rb Purchase_invoices_controller.rb

def new
  @vehicle = Vehicle.new
  @purchase_invoice = @vehicle.purchase_invoices.build
end

def create
  @vehicle = Vehicle.new
  @purchase_invoice = @vehicle.purchase_invoices.build(invoice_params)

  if @purchase_invoice.save
    redirect_to @purchase_invoice
  else
    render 'new'
  end
end

private

def invoice_params
  params.require(:purchase_invoice).permit(:buyer, :location, :vehicle_price, :transfer_fee, :balance_due, :payment_cash, :payment_bank_transfer, :payment_comment, :status, vehicle_attributes: [:vrm, :date_first_registered, :make, :model, :colour, :transmission, :vin, :fuel, :power])
end

new.html.erb new.html.erb

<%= form_with model: @purchase_invoice, local: true do |form| %>
  <%= form.fields_for @vehicle do |vehicle_form| %>
  <% end %>
<% end %>

However when I add a second relationship like this: 但是,当我添加这样的第二个关系时:

purchase_invoice.rb Purchase_invoice.rb

class PurchaseInvoice < ApplicationRecord
  belongs_to :customer
  belongs_to :vehicle
  accepts_nested_attributes_for :customer
  accepts_nested_attributes_for :vehicle
end

I get an error saying :'Unpermitted parameters: :vehicle' 我收到一条错误消息:''不允许的参数:: vehicle'

Does anybody know why? 有人知道为什么吗? Also, how would I modify the controller new/create action for build whilst maintaining strong params? 另外,如何在保持强大参数的同时修改控制器的new / create操作以进行构建?

I've been Googling this for four hours now and tried a lot but had no luck. 我已经搜索了四个小时,尝试了很多,但是没有运气。 Thanks in advance to everybody! 在此先感谢大家!

Update 更新资料

Here's my logs: 这是我的日志:

Started POST "/purchase_invoices" for 127.0.0.1 at 2018-03-20 15:10:01 +0000
Processing by PurchaseInvoicesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"JB8py9zNxew6aQ6/za3JHDEb4j8f9HGujTlS6P1Eyhb+5NtPPP47fW7AHBkt9eURcnXg0gh9Mf1DCKCSwvlAbg==", "purchase_invoice"=>{"customer"=>{"name"=>""}, "vehicle"=>{"vrm"=>"SA07SSX", "make"=>"VAUXHALL", "model"=>"MERIVA DESIGN", "colour"=>"Silver", "vin"=>"W0L0XCE7574216645", "date_first_registered"=>"20/03/2007"}, "vehicle_odomoter_reading"=>"", "vehicle_number_of_keys"=>"", "vehicle_mot_expiry"=>"", "vehicle_hpi_clear"=>"", "vehicle_comments"=>"", "buyer"=>"", "location"=>"", "vehicle_price"=>"", "transfer_fee"=>"0", "balance_due"=>"", "payment_cash"=>"", "payment_bank_transfer"=>"", "payment_comments"=>""}, "commit"=>"Create Purchase invoice"}
  Vehicle Load (0.3ms)  SELECT  "vehicles".* FROM "vehicles" WHERE "vehicles"."vrm" = ? ORDER BY "vehicles"."id" ASC LIMIT ?  [["vrm", "SA07SSX"], ["LIMIT", 1]]
Unpermitted parameters: :customer, :vehicle, :payment_comments
    (0.1ms)  begin transaction
    (0.1ms)  rollback transaction
  Rendering purchase_invoices/new.html.erb within layouts/application
  Rendered purchase_invoices/new.html.erb within layouts/application (10.2ms)
  Rendered layouts/_header.html.erb (1.7ms)
Completed 200 OK in 63ms (Views: 54.4ms | ActiveRecord: 0.4ms)

You approach has some issues but you are very close. 您的方法存在一些问题,但您非常接近。 The PurchaseInvoice model belongs to a Vehicle and a Customer , and it stores a customer_id and a vehicle_id . PurchaseInvoice模型属于VehicleCustomer ,并且存储了customer_idvehicle_id That's correct. 没错 As you said in the comment, it is much more than just a join model, because it holds many other data, such as price, transfer fees, etc. Anyway, you are passing a lot of params regarding the vehicle to be purchased, and not the id of the vehicle . 正如您在评论中所说,它不仅仅是一个联接模型,还因为它包含许多其他数据,例如价格,转让费等。无论如何,您传递了许多有关要购买的车辆的参数,并且不是车辆ID In fact, you are creating the vehicle in the PurchaseInvoice create, which makes no sense. 实际上,您是在PurchaseInvoice创建中创建载具的,这没有任何意义。 Moreover, your vehicle_attributes should not be an array, but a hash (because PurchaseInvoice belongs_to :vehicle ; so it is just one), and should only have the vehicle_id . 此外,您的vehicle_attributes不应为数组,而应为哈希(因为PurchaseInvoice belongs_to :vehicle ;因此仅为一个),并且应仅具有vehicle_id And giving that you just need the vehicle_id , you do not need nested_attributes (neither for customer) . 考虑到您只需要vehicle_id ,就不需要nested_attributes (对于客户nested_attributes都不是)。 I would change: 我会改变:

The controller: 控制器:

def new
  @vehicles = Vehicle.all   #All vehicles, to select from the list
  @customers = Customer.all #All customers, to select from the list (unless you use current_user)
  @purchase_invoice = PurchaseInvoice.new
end

def create
  @vehicle = Vehicle.find(params[:vehicle_id])
  @customer = Customer.find(params[:customer_id]) # Or use current_user
  #The above is only needed to check if vehicle and customer exist, but it is not needed below

  @purchase_invoice = PurchaseInvoice.create(invoice_params)

  if @purchase_invoice.save
    redirect_to @purchase_invoice
  else
    render 'new'
  end
end

def invoice_params
  params.require(:purchase_invoice).permit(:customer_id, vehicle_id, :location, :vehicle_price, :transfer_fee, :balance_due, :payment_cash, :payment_bank_transfer, :payment_comment, :status)
end

The view: 风景:

<%= form_with model: @purchase_invoice, local: true do |form| %>

  <!-- This is necessary to choose the customer. If the customer is current_user, just remove it. -->
  <%= form.collection_select(:customer_id, @customers, :id, :name %>

  <!-- This is necessary to choose the vehicle. This is extremely simplified -->
  <!-- The customer should be able to look at many attributes of the car -->
  <!-- to be able to select one to purchase -->
  <%= form.collection_select(:vehicle_id, @vehicles, :id, :make %>

  <!-- All other invoice fields. -->
<% end %>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM