Lets say i have a model "Blog" with :title and :body.
Lets also say that in my view I have input for title, body and a check_box_tag that looks like this
<%= check_box_tag "published" %>
Now, I want to write a custom validation for the :body that should run only if my checkbox "published" is checked.
The question is - how do i get the value of the ckeckbox since :published is not a model attribute?
You can't. Neither should you.
Validations ensure the buisness logic in the context of a instance of a model. Not a request. If you want to provide any other context to a validation you have to pass it into the model - and that data has to be saved somewhere until the validation callback is performed - in an attribute. This does not necissarily mean that it has to be a database column.
If you do want to get an parameter in the controller they can be found in the parameters hash according to the name attribute of the input.
params[:published]
Related
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
1) entry form contains one field (long text) and submit button;
2) stored in the database (and displayed to the user when viewing) two fields: one - from form, the second - calculated based on the one
how to do?
update: what i do:
1) rails new forstackoverflow
2) cd forstackoverflow/
3) rails generate scaffold Note desc:text word_count:integer
4) vim app/views/notes/_form.html.erb
5) Delete div :
<div class="field">
<%= f.label :word_count %><br>
<%= f.number_field :word_count %>
</div>
6) and i want calculate and save to db word_count, but not know how
Edited
If you are using scaffolding, the params are automatically saved to database when form is submitted, which you do not want.
You will need to require the param in your controller using strong params. Access the param using params[input]. Apply logic and save separate params to database exclusively in your controller.
The specific method of word_count can be done like this:
string.split.size
So in the model, make sure you have created two attributes, one for the string and one for the result of word_count. For now let us assume that you are using "words" for string, and "word_count" for total words in string.
In your view create a form field labeled "words", which will be sent to the params hash as such: form[words].
In the controller under the create action, add the following:
#form.words = params[:form][:words]
#form.word_count = #form.words.split.size
#form.save
Do that in model callback, let's say, before_save. Here's an example:
class Note < ActiveRecord::Base
before_save do
self.word_count = self.desc.to_s.split.size
# to_s just in case self.desc would be nil
end
end
This way each time the model is saved, it will save new word count.
I have a form.
Same form is used for creating and editing...
In my model
validate_uniqueness_of :empID
is present..
and in my form on updating, I get the error that empID is already taken..
Is there any way i can exclude this validation in editing..
You can simply define that your validation should only come into effect on create
validates :empID, uniqueness: true, on: :create
"#TheChamp thing is in my edit form i have disabled the option to edit the id.. Since i want the id to be shown as disbaled in that page i cant remove those line for empID with a condition like if params[:action]==edit.. so hope this is the only solution.."
if all you want is for the empID not to be editable when the form is for an existing one... you can indeed check if the form is for editing and just display it like this:
(Assuming that the moel is in a variable called my_model)
# new_record? will only be true for a model that is being created, not edited
<% if my_model.new_record? %>
<%= f.select :empID, options_go_here %>
<% else %>
# don't display the field-here, instead just display the employee-info
<%= my_model.emp.name %>
<% end %>
Your application is doing exactly what you are instructing it to do.
You validate the uniqueness of the empID attribute which is on conflict upon the update request. Instead of only passing the validation upon it's create action you should think your logic through:
Is there any situation where multiple entries hold the same empID?
Why should the empID be unique? is it a primary key?
From my point of view it looks like empID defines a relation between the record and an emp model? if so adjust the validation to make it functional:
class Model < ActiveRecord::Base
belongs_to :emp
validates_presence_of :empID
end
I asked a question earlier about how to structure the data in a simple app I am building to manage content. The answer was to look at Single Table Inheritance and I think it's going to be the ticket.
I've read quite a few examples but one thing that always seems to be left out is how the :type column is actually populated? Do I include a form field w/ a drop down so the user can select the types?
I believe I fully understand how STI works now (the type field takes on the class name) but am still missing something very basic (and probably very obvious, but I'm missing it). Can someone fill me in?
I have a content table like so:
id
type
name
desc
And the different types would be "Site", "Blog", "Photo".
Guessing that you stores all "Site", "Blog", "Photo" information in contents table. When you initiates any object by Content.new, it does not have assigned any value to type field.
But if you initiate any class from "Site", "Blog" or "Photo" which have been actually inherited from "Content" model by-
Site.new or Site.create then it automatically assigns model_name(in this case- Site) in the type field
Similarly if you do Blog.new it will assign Blog in type column and so on.
#jyoseph, yes you are absolutely correct. You can add a drop-down in you new and edit view which will hold the types, in your case "Site", "Blog", "Photo". You can also make a helper in your Application Helper file as follows
def content_type
return ["Site", "Blog", "Photo"]
end
and then in your contents/new.html.erb you can do
<p>
<%= f.label :type %><br />
<%= f.select :type, content_type %>
</p>
Try it, this might work.
Just in case if anyone wants to know more about STI visit my Blog
I would like to know which way is the best to resolve my question :
I have a form in order to select people via a select field. If the name is missing in the select field, a text field is available to add directly the person's name.
- The form in new.html.erb is the format of the new action of the Team controller.
- The list of the people is extracted from the People model.
def new
#team = Team.new
#people = People.all
end
I created an attribute in the Team model to store the new_person text field :
class Team < ActiveRecord::Base
attr_accessor :new_person
...
end
Finally, here's an extract of my view :
<%= f.select :person_id, #people.map { |p| [p.name, p.id] } %>
<%= f.text_field :new_person %>
Obviously, I would like to save the new person in the table Person before saving the data from the form. As usual, the id are saved instead of the names
At this point, I've got two issues :
1/ The params array has the key new_person what doesn't have the table. So it is not possible to use the Team.new(params[:team]) method. Does exist an easy solution to avoid this problem ?
2/ As I need the person_id, how can I get it when the name comes from the new_person field? In using the before_filter method ?
Thanks a lot,
Camille.
1) You should consider using fields_for in your view within your form_for block. This will allow you to specify that the fields within the fields_for block are attributes of a different model, will generate the appropriately named input fields, and allow you to use params[:team] in your controller. See the FormHelper documentation for more on this.
2) While you could do something in your controller to first check for a value in the new_person field, create the record, update the contents of params[:team] with the value of the newly created person and create the team, this feels a bit like a hack to me. Another possible solution which may be less fragile would be to use some JavaScript on the page that would render some kind of modal dialog for the user to create the new person, submit the new person to the person#create controller method, then refresh your drop down. It would probably not be terribly difficult to do this using a jQuery UI modal form (very good example at that link to do what you need) with Rails remote form and unobtrusive JavaScript.
This is probably a more difficult solution to your second question than you are hoping for, but probably more useful in the long run.