I need to check presence validation for the associated attributes every time when the parent model gets updated.
In my user.rb
accepts_nested_attributes_for :histories
has_many :histories
I need to add validation for the histories when the user model gets updated, I know accepts_nested_attributes will take care of the validations while adding the user through forms, I need to check for the validation every time the user model gets updated even in the console,
If I add
validates :histories, presence: true
It will check for record in the histories table, If any record available for the user It will skip the validation for histories, I need to validate every time the object gets updated. Is there any way to validate whether the new record is being created when updating the parent model?
From your description, I think what you may be looking for is validates_associated:
class User < ApplicationRecord
has_many :histories
# validates that the association exists
validates :histories, presence: true
# validates that the objects in the associated collection are themselves valid
validates_associated :histories
end
the validates :attribute, presence: true validator is meant to validate first-class attributes on the model, not relationships. Such things like on a User class validates :email, presence: true, is where it works best.
Is your goal to validate the has_many relationship or test the relationship? If it's a test, you should make a spec that runs a test along the lines of it { should have_many(:histories) }.... obviously depending on your testing framework.
If you're goal is to validate the has many relationship, you may need to write a custom validate method. However, can you share a little more about what exactly your trying to accomplish/what about the has_many relationship you are trying to validate?
Related
I create uniqueness validation in my model to garantice that user_id in table was unique, but I am not sure if association has_one do that.
User model
class User < ActiveRecord::Base
#association macros
has_one :balance
end
Balance Model
class Balance < ActiveRecord::Base
#association macros
belongs_to :user
#validation macros
validates :user_id, presence: true, uniqueness: true #uniqueness is necessary?
end
It is not necessary to have a validates_presence_of for that since it is handled in your database. However, to not have to handle a database error, it is better to do it in your model like you have. Rails built in error handlers for validation will then work.
If your table data shows that it cannot be null/nil, then the validation is on the database itself and will return an error which is much harder to handle. You will get a system error and the Rails 'better errors' message. Which basically is breaking your app.
If you do the model validation as you have in your Model using the...
validates :user_id, presence: true, uniqueness: true
then Rails will allow you to control these error messages within your app. You can choose to ignore them (bad) and have data entry almost silently fail. Or, you can turn on label_errors along with flash messages in your controller to allow users to see what is wrong with the data they are trying to enter on a form.
I have a newbie rails question. I'm trying to make sure a model has at least one association via a HABTM relationship. Basically I have created the following validation:
validate :has_tags?
def has_tags?
errors.add(:base, 'Must have at least one tag.') if self.tags.blank?
end
This works fine when I create a new record. The problem is when I take the model and try to remove the association, doing something like this:
tag = Tag.find(params[:tag_id])$
#command.tags.delete(tag)$
It is permitted, i.e. the association will be deleted. Based on my reading on HABTM associations (http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association), I should "use has_many :through if you need validations, callbacks, or extra attributes on the join model."
I guess my question is how to perform validation on the .delete method for an association. Should I do this manually when I call delete (i.e. run a separate join to count the number of associations before executing a delete), or is there a way to use a validation model when deleting? Here is my model:
class Command < ActiveRecord::Base
has_many :tagmapsorters
has_many :tags, through: :tagmapsorters
validates :text, presence: true
validates :description, presence: true
validates :text, uniqueness: true
validate :has_tags?
def has_tags?
errors.add(:base, 'Must have at least one tag.') if self.tags.blank?
end
end
I appreciate you taking the time to help me.
Dan
Any callbacks that you need should be registered as before_destroy (for validations) or after_destroy (for cleanup) on the join model Tagmapsorter, as that is the record that is actually being destroyed.
I have a Competition and a Competition Entry model, the former includes a form and an optional "Question" field which isn't displayed if the admin user doesn't fill it out.
The Competition Entry model includes an "Answer" field that only needs to be validated if the question is present, but I'm not sure how to achieve that - is there a way to take advantage of the belongs_to/has_many association they have?
You can make validations conditional on a method, and in that method check the associated model.
class CompetitionEntry < ActiveRecord::Base
validates :answer, :presence => true, :if => :validate_answer?
def validate_answer?
!self.competition.question.blank?
end
end
A railscast about conditional validations!
I've been struggling with this for some time now. I'm just trying to get nested attributes to validate on Rails 3.2 with no luck. It's like it's just completely ignoring validations for the nested attributes. Below is an example validation that's not working:
class Invoice < ActiveRecord::Base
validates :description, :presence => true
belongs_to :client_branch
has_many :invoice_items
accepts_nested_attributes_for :invoice_items, :allow_destroy => true
end
class InvoiceItem < ActiveRecord::Base
belongs_to :invoice
validate :thisisatest
def thisisatest
errors.add(:qty, 'QTY NOT VALIDATING TEST.')
end
end
When saving an Invoice with some InvoiceItems, it saves it successfully, even though the custom validation is clearly adding an error for the :qty attribute. Is there something I should be adding to my models for nested validation to work, or am I perhaps missing something else?
Actually, I'm being daft. I changed the model name, along with all references to it and it took me this long to miss one reference still pointing to the old model in the javascript. Thus, items being added dynamically weren't named correctly, causing the validation not to trigger. :/
I have a Category and a Post model, with each Post belonging to a Category. Before creating or updating a post, I need to check that the category selected exists. What's the best way to validate this information?
At the moment, I'm doing a find in the controller to ensure that the category exists. Is it possible to put these kinds of validations in the model?
http://blog.hasmanythrough.com/2007/7/14/validate-your-existence
class Post < ActiveRecord::Base
belongs_to :category
validates_presence_of :category
end
-OR-
class Post < ActiveRecord::Base
belongs_to :category
validates :category, presence: true
end
Rails versions prior to 3.2:
class Post < ActiveRecord::Base
belongs_to :category
validates_existence_of :category
end
In Rails 3.2, validates_existence_of is replaced by validates_presence_of.
I've put this in my model:
validate :ensure_category_exists
def ensure_category_exists
errors.add('Category') unless self.blog.categories.find_by_id(self.category_id)
end
Which prints "Category is invalid" if the category does not exist for the parent blog.
It's definitely worth mentioning my experiences. This is for Rails 4 (potentially other versions as well).
Given an entity has_many or has_one of a model.
Validation that will ensure the entered association (association ID) exists, even if there is an ID given in the submission.
validates_presence_of :model
IS NOT THE SAME as a validation that will ensure there is something entered (not blank) in the input.
validates_presence_of :model_id
You may be able to get by with just the former, but I have both to have more specific error messages.
In my way of thinking a better choice is this gem: https://github.com/perfectline/validates_existence
It validates the related model's existence in the database. Imagine you have a dropdown field that gives back some garbage data even when you do not select anything (default non selected first field label as value). Validating presence won't work, as it will pass for existing data. But we want some kind of a constraint and this DB side check is what solves the problem.
In rails 5 and above, belongs_to automatically validates for presence.
But if you use belongs_to :category, optional: true it does not validate presence, and you can then do post.update!(category: -1) which is not great. To fix that:
validates :category, presence: true, if: :category_id
Just to be clear, the above is useful only when the association is optional.
In Rails 3, validates_associated is probably what you're looking for?
http://guides.rubyonrails.org/active_record_validations_callbacks.html#validates_associated