Reputation: 3
I have two model Product
and ProductBoxing
, product has many product_boxings.
product.rb
class Product < ActiveRecord::Base
has_many :product_boxings
accepts_nested_attributes_for :product_boxings
validates :name, presence: { presence: true, message: 'please give a name' }, on: :update
end
product_boxing.rb
class ProductBoxing < ActiveRecord::Base
belongs_to :product
validates :quantity, presence: { presence: true, message: 'please fill in quantity' }, on: :update
end
_form.html.erb
<%= form_for(@product, html: {class: "form-horizontal", role: "form", multipart: true}) do |f| %>
<%= f.text_field :name%>
<%= f.fields_for :product_boxings do |g| %>
<%= g.text_field :quantity %>
<% end %>
<% end %>
For some reasons, I create both product
and product_boxing
without validation first. After that, I want to validate both on updating. The validation works for Product
, but not for ProductBoxing
.
Are there any problem in my code? or it is a rails issue?
BTW, I remove validation option on: :update
and validate both on creating, the validations work for both.
At first, user will ran the follow code
def new
product = Product.new
p_b= product.product_boxings.build()
product.save!
redirect_to edit_product_path(product)
end
then
def edit
end
and post form
def update
@product.update(product_params)
unless @product.errors.any?
redirect_to products_url
else
render 'edit'
end
end
def product_params
params.require(:product).permit(:name, product_boxings_attributes:[:id, :quantity] )
end
Upvotes: 0
Views: 777
Reputation: 3052
You should ensure the validation of your associated model:
class Product < ActiveRecord::Base
has_many :product_boxings
validates_associated :product_boxings
# ...
end
http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates_associated
TEST THE MODELS WITH THE CONSOLE
> p = Product.new
> p.valid?
> p.errors
> p.product_boxings.each { |pb| pb.valid?; pb.errors }
If you want to see this product_boxings messages in the error list, you should create a custom validation.
validate :associated_product_boxings
def associated_product_boxings
product_boxings.each do |product_boxing|
errors.add (...) unless product_boxing.valid?
end
end
Upvotes: 0