Reputation: 471
I have an exercise called "BillApp" basically it's a Bill that have some products, and i should could make bills, calculate IVA, etc.
I have the next schema:
create_table "bill_items", force: :cascade do |t|
t.integer "amount"
t.integer "product_id"
t.integer "bill_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["bill_id"], name: "index_bill_items_on_bill_id"
t.index ["product_id"], name: "index_bill_items_on_product_id"
end
create_table "bills", force: :cascade do |t|
t.string "user_name"
t.string "dni"
t.date "expiration"
t.float "sub_total"
t.float "grand_total"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "products", force: :cascade do |t|
t.string "name"
t.string "description"
t.float "price"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Bill model:
class Bill < ApplicationRecord
has_many :bill_items
has_many :products, through: :bill_items
accepts_nested_attributes_for :bill_items
end
BillItem model:
class BillItem < ApplicationRecord
belongs_to :product
belongs_to :bill
end
Product model:
class Product < ApplicationRecord
has_many :bill_items
has_many :bills, through: :bill_items
end
The ProductsController is a normal one, generated by scaffold, it doesn't matter.
BillsController:
class BillsController < ApplicationController
before_action :set_bill, only: [:show, :update, :destroy, :edit]
def new
@bill = Bill.new
@bill.bill_items.build
end
def create
@bill = Bill.new(bill_params)
byebug
@bill.save
end
private
def set_bill
@bill = Bill.find(params[:id])
end
def bill_params
params.require(:bill).permit(:user_name, :dni, { bill_items_attributes: [:product_id, :amount, :bill_id] })
end
end
And finally the Bill new view:
<%= form_for(@bill) do |f| %>
<div>
<%= f.label :user_name %>
<%= f.text_field :user_name %>
</div>
<div>
<%= f.label :dni %>
<%= f.text_field :dni %>
</div>
<%= f.fields_for :bill_items do |fp| %>
<div>
<%= fp.label :product %>
<%= fp.collection_select :product_id, Product.all, :id, :name %>
</div>
<div>
<%= fp.label :amount %>
<%= fp.number_field :amount %>
</div>
<% end %>
<%= f.submit %></div>
<% end %>
The problem is very specific, in rails 5 when it try to call @bill.save it fails and in the errors it shows:
#<ActiveModel::Errors:0x007fd9ea61ed58 @base=#<Bill id: nil, user_name: "asd", dni: "asd", expiration: nil, sub_total: nil, grand_total: nil, created_at: nil, updated_at: nil>, @messages={:"bill_items.bill"=>["must exist"]}, @details={"bill_items.bill"=>[{:error=>:blank}]}>
But it works perfectly in Rails 4.2.6. The entire project folder is here: https://github.com/TheSwash/bill_app currentrly in the branch feature/bills_controller
Somebody have an idea about what's happening?
Upvotes: 1
Views: 780
Reputation: 1159
the problem it's the bill_items validation
In rails 5 the belongs_to association required by default
http://blog.bigbinary.com/2016/02/15/rails-5-makes-belong-to-association-required-by-default.html
Upvotes: 1