rails 4 validating associated object + db constraint

I'm trying to add validation to foreign key fields in rails and constraints in postgres db.

Let's say there is a user. User has_many :products and product belongs_to :user. In this case the situation is easy since user is created for sure when a new product gets added. So validates: user, presence: true can be added to the product model and user_id, null: false can be added in the postgres db.

But what if the parent child object and the object get created at same time. Let's say in the product form I have product_features as nested attributes. So product has_many :product_features and product_feature belongs_to :product.

According to Rails 4 Way: "When you’re trying to ensure that an association is present, pass validates_presence_of its foreign key attribute, not the association variable itself. Note that the validation will fail in cases when both the parent and child object are unsaved (since the foreign key will be blank)."

How can I implement the model validations and the db constraints on foreign key fields in this case?

Answers


Truth is that validating the presence of the key itself (eg. product_id) is fairly useless anyway, because @product_feature.product_id = -25 will pass validation.

I always do the presence validation on the association:

validates :product, presence: true

That will work no matter which way you create your objects:

ProductFeature.new product: Product.new

...or...

Product.new product_features: [ ProductFeature.new ]

I'm not sure why anyone would recommend anything else, validating on the key itself does not guarantee that the key exists in the DB.


In this case, you can just create your custom validation method in model.

Write the following validation method in Product model to ensure that a product has product_features.

 validate :product_features

 def product_features
   product_features.present?
 end

This doesn't answer your question directly, but when using nested forms you should build the object like:

Product.product_features.new

This way you will be sure that you have product_id in product_feature


Need Your Help

Prevent user to access if has not logged in

php html

I am currently working on developing a simple web system, so an user first will be directed to a login page, then a processing page. If its account data provided is correct, it will be directed to ...

How to setup the passwords-less authentication between two different accounts

linux ssh ssh-keys system-administration password-less

Can we setup a password less authentication between two different uses in two machine.