I want to know how to validate that a user selected a value.
My collection_select is:
= f.collection_select :person_id, #employee, :id, :fullName, {prompt: "Select employee"}, {class: "form-control"}
I would use:
validates :person, :presence => true
This ensures that the selected person_id was not only present, but it also belongs to an existing Person.
Please note that if there are errors the errors will be added on :person, not on person_id. Depending on how you render validation errors you will have to check for error like this: object.errors[:person].
When you want to present errors next to the person_id field, but cannot update your view, then you might want to use a custom validation that checks person, but adds errors to person_id:
validate :person_existing
private
def person_existing
errors.add(:person_id, :missing) if person.blank?
end
For view tests in general, I would write a test against the returned HTML from the controller action. This gives the benefit of not doing in-browser tests (i.e. you don't have to use a web driver/headless browser), and since it's up to the individual browsers to render your HTML properly you can keep you tests simpler by just ensuring that the returned HTML from the controller action is correct.
If you want to validate that, when the user selects a given item, that it has been selected...well that's really up to the browser to do that job, so I don't know if you really want to test that. However, you should be able to check for the selected attribute on the tag (see here)
That said, in general don't go too crazy with view tests, if this is indeed what you're going for. The view is the part of most apps that changes very frequently, and is quite fragile. You may find yourself chasing view changes a lot in your test suite.
Related
I want to add 'Notice that you have to select all the images and related vehicles again.' to the end of any validation error, regardless of how many errors there are, so for example adding this text to the end of every error message isn't an option, because it will be shown many times if there is more than one error.
Is there any way to add particular text to the end of validation error message?
Tried to google but didn't found anything.
This is easily accomplished however it may be tedious depending on how many validations you have listed. I will give some examples so you can decide on what best suites your needs:
If using Rails' built-in validations (such as prescence, uniqueness, etc.) you can add your own message inside the validation along with the standard output or replace it completely with your own:
validates :username, :email, :title, :another_attribute,:omg_another_attribute, :password, presence: { :message => "cant be blank. Notice that you have to select all the images and related vehicles again for not filling out the form ya dumbo!"}
This will list the error message for every field they left blank. If you want to add an error just once at the end of all the error messages to remind them of this problem you can make a custom validation that checks for other errors and then appends its own, one time, at the end like:
#Make sure to put this custom validate method after all the other validators since they are run in order from top to bottom and you want to see if the others have failed
validate :add_blanket_error_when_one_or_more_errors_happen
def add_blanket_error_when_one_or_more_errors_happen
if self.errors.count > 0 then self.errors.add(:base, "Notice you were being dumb again and now have to fill more stuff out.") end
end
I normally add generic errors like this to the 'base' field but you can attach it to any field in your form if you dont want to add extra styling/markup. In your view if you chose to add it to the 'base' field you can put this message right at the top of the form if it exists by doing:
<% unless #the_form_object_youre_using_here.errors[:base].blank? %>
<div>
<span class="error-explanation"><%= #again_the_form_object_here.errors[:base].first %></span>
</div>
<% end %>
This will also let you style the span etc.
Unfortunately there is no simple one-liner you can add to your model to append a blanket message to all failed validations. Even trying something seemingly harmless like a custom validation to accomplish it(DONT TRY THIS UNLESS YOU HAVE your task-manager ready because it will cause a memory leak and even make your computer crash if you dont kill the process quickly)
**DONT DO IT IF YOU ENJOY COORS LIGHT OR PREFER LONG WALKS ON THE BEACH**
validate :append_messages_to_all_failed_validations
def append_messages_to_all_failed_validations
self.errors.each do |attribute, error|
#**YOU SHOULDNT BE DOING THIS LOL**
self.errors[attribute.to_sym] = "#{error} plus some"
end
end
I have a question about how can I validate a required change at rails model.
for example:
to the param lock_version we need the validate if this value always is present when tried to update the model.
has rails some validation to test the change presence?
Thanks
This type of validation is handled by validates_presence_of.
Seems like you're looking for
validates_presence_of :lock_version, on: :update
I strongly advise to take a look on http://apidock.com/rails/ActiveRecord/Validations/ClassMethods/validates_presence_of
There are plenty of validations in Rails and this is probably the most basic one.
http://guides.rubyonrails.org/active_record_validations.html
#jakub is right, however if you want another way of validating fields you can use html validations. Add required: true to any field you need to be filled out. I.e
<%= f.text_field :lock_version, required: true %>
If a user tries to submit the form without this field they will get a flash message pop up over the field telling them to fill it out.
Justin
I have a form used for creating a team (the model is Team).
The form adds members to the team (via the model TeamMember).
Each team works for a company. All users belong to a company.
I currently have a validation on the TeamMember model which prevents a user from becoming a team member when the user works for a different company than the team works for.
Recently, I've been asked to modify this functionality, since there are occasions when a team needs to add a member who works for a different company.
My simple validation has now become complicated.
I now need to provide a warning when a proposed team member works for a different company, and give the user a chance to confirm (yes/no) whether this is ok before saving the change.
What is a clean, rails-friendly way to accomplish this? I imagine there is an Ajax solution (maybe a lightbox), but I'm not sure the best way to implement it or whether someone already has a clever Gem/Plugin to handle this situation.
I would use a custom validation for this, as you are now, and add a modifiable attribute to the model that doesn't save to the db. For example:
class TeamMember < ActiveRecord::Base
attr_accessor :user_confirmed
after_intialize :setup
def setup
self.user_confirmed = false
end
end
What you need to do is add a check in your validation method if self.user_confirmed is false. If it is, in addition to the db relation you described above, make it invalid. Then on your view, add an if statement:
<% if #team_member.errors[:key_you_use_to_add_to_base].first == "Error Message" %>
<%= f.label :user_confirmed, "User works for another company, are you sure?" %>
<%= f.check_box :user_confirmed, {}, "true", "false" %>
<% end %>
Keep in mind since check_box method uses strings, youll need to convert the result of that attribute in your params hash to a boolean.
I think that should do it. Note that you may need to adjust the if statement if any other validation errors might be added to the same key.
I've begun using Formtastic in the last couple days and have come to my first head-scratcher.
I'm working with items that each have a few associated accounts. On the page in question you need to select a payee account. It can either be an account we already know about (the "Main Contact") or a new account that you can create by filling in a little information.
Here's the design I'm trying to replicate:
Using Formtastic it's very simple to display a form to enter a new account's information.
<%= form.inputs :street, :city, :for => :address %>
It's also very simple to create a radio selection list of available accounts.
<%= form.input :address, :as => :radio, :collection => #addresses %>
The problem I'm puzzling over, as the above pic illustrates, is how to do both - select an existing account or create a new one.
Well, the real question is how to do both gracefully. Anything I've thought of seems to add logic to the controller and leaves me suspecting that there's a graceful solution that I'm not seeing (having dived into RoR recently, this is a very familiar feeling).
Can't see a solution that wouldn't add a few lines to a controller. Although "Fat models, thin controllers" is a nice principle, it's not always possible to have "one-liner" restful methods, with a before filter on top setting up variables for views.
So what "level of gracefulness" we are talking about? ;) Maybe you could post a solution you consider and other members would comment on it or rate it?
I tried the example from Rails Cookbook and managed to get it to work. However the text_field_with_auto_complete works only for one value.
class Expense < ActiveRecord::Base
has_and_belongs_to_many :categories
end
In the New Expense View rhtml
<%= text_field_with_auto_complete :category, :name %>
Auto complete works for the first category. How do I get it working for multiple categories? e.g. Category1, Category2
Intended behavior: like the StackOverflow Tags textbox
Update:
With some help and some more tinkering, I got multiple comma-seperated autocomplete to show up (will post code-sample here).
However on selection, the last value replaces the content of the text_field_with_auto_complete. So instead of Category1, Category2.. the textbox shows Category2 when the second Category is selected via auto-complete. Any ideas how to rectify this?
If you are just trying to support multiple instances of autocomplete per field, you can pass a delimiter to the autocomplete options with the symbol :token. This provides a delimiter to allow multiple results. Stackoverflow would use :token => ' ' (there should be a space between the quotes, but the autoformat is removing it) to specify space at the delimiter between multiple takes although ',' is more commonly used.
This is not quite your question, but I wouldn't recommend using HABTM anymore. You should create a join model and use has_many :through. (In your case you'd create a new model called ExpenseCategoryAssignment, or something)
The problem is that HABTM creates ambiguities that rails doesn't like, and it tends to expose bugs you wouldn't see otherwise.
You need to use "data-delimiter" param like this
<%= f.autocomplete_field :brand_name, welcome_autocomplete_brand_name_path, "data-delimiter" => ', ' %>