Reputation: 11
I've a multiple relation table named Order which belongs_to a Relai(to avoid singular/plurials complications), a Customer and a Composition. I set my Order model accordingly with nested_attributes as mentioned below. Before adding the customer part, I want to send a mail with just the @composition and a @relai chose with a dropdown.
class Order < ApplicationRecord
belongs_to :relai
belongs_to :composition
accepts_nested_attributes_for :relai
accepts_nested_attributes_for :composition
end
I set my OrdersController to get the :composition_id from my params
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
My View:
<%= 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 %>
And the routes:
resources :compositions, only: [:show, :index] do
resources :orders, only: [:show, :new, :create, :index]
end
I also tried:
"nested_attributes" which seems to not works (I can't see my Relai collection in view. => https://www.pluralsight.com/guides/ruby-on-rails-nested-attributes)
the "optional: true" in model which throw me an error of:
PG::NotNullViolation: ERROR: null value in column "relai_id" of relation "orders" violates not-null constraint
Can someone explain me why I got a "Validation failed: Relai must exist, Composition must exist" whereas these appears in my params?
{"authenticity_token"=>"[FILTERED]", "order"=>{"relai"=>"2"}, "commit"=>"MAIL", "composition_id"=>"3"}
I'm on Rails 6.1.4 ; Ruby 2.6.6
Upvotes: 0
Views: 187
Reputation: 1951
accepts_nested_attributes_for
works from parent to children. You are using it on the child side (Order
).
If you just need to assign an existing Relai
and Composition
to Order
just use a select for both of them:
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 %>
EDIT: Setting Composition on the controller.
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 %>
Upvotes: 0