Rails 4 - Checkbox and Boolean Field - ruby-on-rails

I have looked at loads of different articles on the web (some on here) about this issue but there are so many different suggestions, lots of which are outdated, that it has led me to ask here today...
I have a field in my Users table called admin? which is a :boolean data type. I also have a checkbox in the form in my view called admin? - I would like to be able to create TRUE and FALSE accordingly in the table record when the form is submitted.
Part of my view code is:
Admin User? <%= f.check_box :admin? %>
Also I have permitted this in my post_params - is this a necessary step?
params.require(:staff).permit(:name, :email, :password, :password_confirmation, :admin?)
When I submit the form at the moment, the admin? field is unaffected. Any advice would be much appreciated.

No need to name it ":admin?"
Just use this in your form:
Admin User? <%= f.check_box :admin %>
And the permitted params like this:
params.require(:staff).permit(:name, :email, :password, :password_confirmation, :admin)
That should work.

For anyone that has a form that isn't part of an object.
I found using checkbox syntax like:
= check_box 'do_this', '', {}, 'true', 'false'
Then in the controller side:
ActiveRecord::ConnectionAdapters::Column.value_to_boolean(params[:do_this])
Will give you the correct boolean value of do_this.
Examples:
[1] pry(main)> ActiveRecord::ConnectionAdapters::Column.value_to_boolean("true")
=> true
[2] pry(main)> ActiveRecord::ConnectionAdapters::Column.value_to_boolean("false")
=> false
[3] pry(main)> ActiveRecord::ConnectionAdapters::Column.value_to_boolean("1")
=> true
[4] pry(main)> ActiveRecord::ConnectionAdapters::Column.value_to_boolean("0")
=> false
Edit:
The above is deprecated, use:
ActiveRecord::Type::Boolean.new.type_cast_from_database(value)
It gives the same results as the examples above.
Rails 5
The above options don't work in Rails 5. Instead, use the following:
ActiveRecord::Type::Boolean.new.cast(value)

It's possible you have not allowed your controller to accept the admin field through params. In other words, an issue of strong parameters. Ensure that :admin is permitted in your model_params.

Related

Do form validation that does not use database

I have a form and I have made some inputs required. After submitting the form that value will be sent to an API. I know that the validations are put into model file but since I do not have a database, how can I use the rails validation?
Right now I am validating the code inside a controller using if else.
if !params[:groups][:name].blank? && !params[:groups][:make].blank? && !params[:groups][:model].blank? && !params[:groups][:firmware].blank?
This does the work but it is not very elegant.
Take a look at ActiveModel, it lets you do "model things" without the database. There were some limitations that made me not use it in the end (I think related to associations) but for simple stuff it's great (and it's a part of how ActiveRecord works.
Example code from docs
class Person
include ActiveModel::Model
attr_accessor :name, :age
validates :name, :age, presence: true
end
this is easy. On the form input fields that you NEED, add required: true For example:
<%= form.for #something do |f| %>
<%= f.text_field :title, placeholder: 'Title', required: true %>
<% end %>
The user gets an error if the required fields are not filled out correctlty.
Is this what you mean?
Justin
EDIT
I guess I would look at using the gem
client_side_validations
Let us know how you go

How do you make a rails multi select dropdown work

I am trying to make a multi select dropdown work with a dialog for search parameters. I can make the dropdown multi select but can't seem to get/pass the resulting data. (edited/new info will be in italics)
I believe that the root of the problem is that I need to change the permit section in my controller to reflect that I am passing a hash/array. If I look at the resulting record, the 2 fields that I am setting as multi-selects show as nil. However, if I force an errror, the parameters shown by rails show the correct choices. therefore, I believe that the problem might be with the permit section.
That looks like
*def search_params
params.require(:search).permit(:document_title,
:summary,
:owner,
:category,
:file_name,
:doc_to_email,
:categories_attributes => [:name])
end*
I added the :categories_attributes => [:name] to try to get the controller to allow hashes but that didn't work.
The select field is
<%= f.select :category[], options_for_select(#categories.sort), {:include_blank => true}, {:multiple => true, :size =>10} %>
but that gives me
.erb where line #41 raised:
wrong number of arguments (0 for 1..2) Trace of template inclusion:
app/views/searches/new.html.erb
I thought I had to set category as an array with the [] but obviously I'm missing something.
Category is a string field in the Searches table.
You do not need the [] brackets after the field name as Rails adds those in automatically.
See the example here:
http://apidock.com/rails/ActionView/Helpers/FormTagHelper/select_tag
select_tag "colors", "<option>Red</option><option>Green</option><option>Blue</option>".html_safe, multiple: true
# => <select id="colors" multiple="multiple" name="colors[]"><option>Red</option>
# <option>Green</option><option>Blue</option></select>
In your case the selected values will be available as an array in params[:search][:category] after the form is submitted.
If you use strong parameters, also make sure you have :category => [] in the permit list.

validates :terms, acceptance: true not showing error

In my model I have the following validator:
validates :terms, acceptance: true, on: :create, allow_nil: false
attr_accessor :terms
and in my form I have:
= simple_form_for #reservation do |f|
= f.error_notification
= f.input :terms, as: :boolean
The problem is that when user not accept the terms it not showing any error, why?
Try this:
validates :terms, :acceptance => {:accept => true} , on: :create, allow_nil: false
Problem may have terms as an actual column in the table. In general validates_acceptance_of is used without such a column, in which case it defines an attribute accessor and uses that for its validation.
In order for validates_acceptance_of to work when it maps to a real table column it is necessary to pass the :accept option, like:
validates :terms, :acceptance => {:accept => true} , :on => :create , allow_nil: false
The reason for this has to do with typecasting in Active Record. When the named attribute actually exists, AR performs typecasting based on the database column type. In most cases the acceptance column will be defined as a boolean and so model_object.terms will return true or false.
When there's no such column attr_accessor :terms simply returns the value passed in to the model object from the params hash which will normally be "1" from a checkbox.
Via noodl
I may have had a similar problem (Rails 4.2.0). I created a checkbox, but it would be ignored and never report and error if unchecked. I found that adding the parameter to the .permit part of my Strong Parameters allowed it to be present.
In my view template for my _form I have something like this:
<div class="field">
<%= label_tag :tos, 'I accepts the TOS' %><br>
<%= f.check_box :tos %>
</div>
I generated my model using scaffold, so my create method start like this
def create
#thing = Thing.new(thing_params)
then near the bottom I have the following for thing_params
def thing_params
params.require(:thing).permit(:field1, :field2, :tos)
end
in my model I used the following:
validates_acceptance_of :tos
If I leave out ':toslike thisparams.require(:thing).permit(:field1, :field2) it will not pop up an error and allows it to continue. This seems counter-intuitive because if Strong Parameters is removing the :tos field then I would think the validate_acceptance would fail.
I had initially just create a checkbox without using f.check_box. Now, if I even try to call the new route without :tos" being listed as permitted, rails throws an error. There also seems to be some rails magic going on because if I remove the validates_acceptance_of from my model, I receive an NoMethodError error when rendering my view saying undefined methodtos'` for the line
<%= f.check_box :tos %>
Would be great if someone else could explain what exactly is going on as I just hacked this together from googling and guessing.

How to set a field read only in rails 3.1.0 views?

My question is how to set a field in rails form read only. The following is a selection box in quotes controller. Users are not allowed to change the selection.
<% #quote.test_items.each do |t| %>
<%= f.association :test_items, :label => false, :selected => t.id %>
<% end %>
The app uses simple_form. Thanks so much.
I've encountered a similar problem, thankfully, there is a simple resolution.
The basic issue is that if you use :disabled => true with simple_form you will not see that value back in the controller. When you pass an object from HTML form to later bind it to the model - you need all of those attributes. The :disabled => true however does not pass any such attribute.
The solution to this is to use :readonly => true - it will protect the field from user entry and it will still pass the param value back to the controller so you can bind everything to your model.
Good luck.
See https://github.com/plataformatec/simple_form/pull/367
I believe you'd just pass in :disabled => true. It's been my experience that options 'just work' with simple_form. So in your case:
<% #quote.test_items.each do |t| %>
<%= f.association :test_items, :label => false, :disabled => true, :selected => t.id %>
<% end %>
From the simple_form github repo:
It is also possible to give the :disabled option to SimpleForm, and it'll automatically mark the wrapper as disabled with a css class, so you can style labels, hints and other components inside the wrapper as well.
Yes, what #gk0r said, as it is documented here:
NOTE: The HTML options disabled, readonly, and multiple can all be treated as booleans. So specifying :disabled => true will give disabled="disabled".
*disabled will have slightly different behavior than readonly.
The top answers above are all wrong.
disabled attribute has a different behaviour than readonly.
read and compare them:
http://www.w3schools.com/tags/att_input_disabled.asp
Tip: Disabled elements in a form will not be submitted.
http://www.w3schools.com/tags/att_input_readonly.asp
The right answer is to use
:readonly => true
something like this:
<%= f.association :test_items, :label => false, :readonly => true, :selected => t.id %>
It's not clear to me if the association method accepts HTML options or not, but if it does, you can pass disabled: 'disable' to make it read-only with a fixed value.
I think you might be able to choose the fixed value by passing association as block, as shown in the association docs:
f.association :company do |c|
c.input :name, selected: 'selection'
c.input :type
end
As to whether or not the entire list can be read-only and still drop-down, the only solutions I see from google involve JS, for example:
http://techeyes.blogspot.com/2007/11/making-html-select-readonly.html

Accept Rails model attribute only if it was previously blank

I have a Rails model (persisted with Mongoid) that can be collaboratively edited by any registered user. However, I want to allow editing any particular attribute only if it was previously blank or nil.
For example, say someone created an object, and set its title attribute to "Test Product". Then another user comes along and wants to add a value for price, which until now has been nil.
What's the best way to do this, while locking an attribute that has previously been entered?
Look into the ActiveRecord::Dirty module for some nice utility methods you can use to do something like this:
NON_UPDATABLE_ATTRIBUTES = [:name, :title, :price]
before_validation :check_for_previously_set_attributes
private
def check_for_previously_set_attributes
NON_UPDATABLE_ATTRIBUTES.each do |att|
att = att.to_s
# changes[att] will be an array of [prev_value, new_value] if the attribute has been changed
errors.add(att, "cannot be updated because it has previously been set") if changes[att] && changes[att].first.present?
end
end
The easiest way, i think, is by checking for it in the form itself.
Just say add :disabled => true to the input field if the person cannot edit it.
<% if #my_object.name %>
<%= f.text_field :name, :disabled => true %>
<% else %>
<%= f.text_field :name, :disabled => true %>
<% end %>
(i think there is a prettier way to write this code)
But by using this the user has a visual feed back that he can't do something, it is always better to not allor something than to give an error message

Resources