How to create a rails checkbox form? - ruby-on-rails

Im trying to create a checkbox table of about 20 "interests" that lets the user select as many as they want. I have a Interest & User model with a HABTM relationship (through a "interests_users"join table).
So:
How do i seed the interests table (just has a name:string attribute) with the names of 20 or so pre set interests?
How do i display these in a ERB form allowing the user to select as many as they like?
Note.. Im using the Wicked gem to create a multistep form (<-working great)

If you're on Rails >= 3.0, then have a look the db/seeds.rb file. You get to put arbitrary Ruby code in that file, which you run through the Rake task rake db:seed. You can just put a lot of lines like Interest.create :name => 'World Domination'.
This one is going to depend on how you set up your form. Going off the information you've given, I'd do something like this:
<%= form_for #user do |f| -%>
<% Interest.all.each do |i| -%>
<div><%= i.name -%> <%= check_box_tag 'user[interests][]', i.id, #user.interests.detect{|ui| ui.name == i.name} -%></div>
<% end -%>
<% end -%>
In your controller you would then be able to just update your user model's attributes. Be sure to make sure you are able to mass-assign your parameters, and also keep in mind a limitation of the HTML spec with regard to unchecked checkboxes (read the part titled, "Gotcha").
EDIT: fixed some grammar-related typos.

<% for interest in Interest.find(:all) %>
<%= check_box_tag "user[interest_ids][]", interest.id, #user.interests.include?(interest) %>
<%= interest.name %>
<% end %>

Related

Rails habtm checkboxes on create

Is possible to utilize the habtm checkboxes on create action?
because this:
<%= hidden_field_tag "product[size_ids][]", nil %>
<% Size.order(:size).each do |size| %>
<li> <%= check_box_tag "product[size_ids][]", size.id, Product.size_ids.include?(size.id), id: dom_id(size) %>
<%= label_tag dom_id(size), size.size %>
</li>
<% end %>
was on update and was working since was brought to create page rails spits out the
undefined method `size_ids' for #
so, have a way to utilize the habtm on a create action?
Since you're likely dealing with one item, you probably mean:
#product.sizes_ids
The Product model doesn't have a direct association with any sizes, it's only instances of it that do.
use collection check boxes getting all of the model with ids exemple:
<%=p.collection_check_boxes :size_ids, Size.all, :id, :size %>

Using ! with object name in ruby on rails

I have a column "SchoolName" in my educations table and I want to check the following code:
<% #user_education.each do |e| %>
<% if !e.SchoolName.nil? and e.Private? == "1" %>
<%= check_box(:ChkBx_Education, "", true) %>
<%= label(:lb_Profession, "Education") %>
<% else %>
<%= check_box(:ChkBx_Education,"" ) %>
<%= label(:lb_Profession, "Education") %>
<% end %>
<% end %>
The #user_education variable comes from the controller page i.e #user_education=Education.where(:UserID => current_user.id) My question is whether this statement !e.SchoolName.nil? is right or wrong? I want to ensure that if SchoolName is not nil and Private? is equal to "1" then it checks the checkbox.
As per the comments, you need to rename your database columns to be lower case in order to make initial syntax improvements:
<% #user_education.each do |e| %>
<% if e.school_name && e.private? %> =-> .private? should return true / false if column is boolean
<%= check_box(:checkbox_education, "", true) %>
<%= label(:checkbox_education, "Education") %>
<% else %>
<%= check_box(:checkbox_education,"") %>
<%= label(:checkbox_education, "Education") %>
<% end %>
<% end %>
Buddy, you have broken the rules of developing an application with Ruby.
Active Record uses naming conventions for the columns in database tables, depending on the purpose of these columns.
The names of attributes in Ruby should always be uncapitalised, just like local variables.
Foreign keys - These should be named following this pattern: singularized_table_name_id (ex: item_id, order_id). These are the fields that Active Record will look for when you create associations between your models.
Primary keys - By default, Active Record will use an integer column named id as the table's primary key. When using Rails Migrations to create your tables, this column will be automatically created.
I think you should refer to Ruby Guides and read it carefully before working with any application.
The correct convention of the following line would be something like this, taking Private? as a boolean columns. The correct code following rails convention would have been something like this
<% if e.school_name.present? and e.is_private? %>

Syntax for form_for when building an array from checkboxes

I'm making a form for an Order object, and the order has many Products, via a join table called OrderProducts. So, we've got something like this:
<% #order = Order.new %>
<% form_for #order do |f| %>
<% #products.each do |product| %>
... want to iterate over products here to build up "order[product_ids][]", with one checkbox per product
<% end %>
<% end %>
Usually for each product i would have a check_box_tag, saying
<%= check_box_tag "order[product_ids][]", product.id, #order.product_ids.include?(product.id) %>
But this, while working fine, always feels like a bit of a cop out. Is there a way i can do it with the f.check_box syntax? Important note - on the project in question I'm working in Rails 2.2.2, so a solution that works in rails 2 would be ideal.
Rails <= 2.x (original)
<% #products.each do |product| -%>
<% fields_for 'product[]' , product do |product_fields| -%>
[...]
<%= product_fields.check_box :id %>
<% end -%>
<% end -%>
Rails >= 3.x (updated)
<% #products.each do |product| -%>
<%= fields_for 'product[]' , product do |product_fields| -%>
[...]
<%= product_fields.check_box :id %>
<% end -%>
<% end -%>
I know the author was looking for version 2 answers, but this is the top hit for google and I though I would update:
One can do this ( I'm using 4.0, don't know how far back it goes ):
<%= form_for #order do |form| %>
<%= form.collection_check_boxes(:product_ids, Product.all, :id, :labeling_method ) %>
<% end %>
For more info: http://edgeapi.rubyonrails.org...
I've done a number of multi checkbox forms over the years and different Rails version. Rails has never provided any really clean way to do it, but the "cop out" solution you came up with is pretty good isn't it? It's one line, it's explicit, and as long as the list of products is reasonably short it will perform adequately.
To answer your specific question, f.check_box will never work for this. It's just short hand for the check_box_tag, but none of the semantics apply. If you want to go Rails native, the only possibility I think is to use nested attributes. Part of the problem is that there is not one obvious way for this type of thing to work. Rails core went through a lot of planning and feedback to come up with nested attributes as they exist, and though they seem a bit obtuse, they capture the most common use cases quite elegantly. But nested attributes were introduced in Rails 2.3, and besides they will introduce quite a bit of conceptual overhead for something which sounds like it doesn't need the complexity.
There are also some plugins that provide helpers for this, although I haven't used any in a long time (since Rails 2 era actually). My impression is that they too are overkill unless you have many forms that make use of this pattern.
In short, I think you should go ahead with your existing solution.
formastic gem
check_boxes option is very good to implement multiple checkboxes
like
f.input :yourcolumn, :as => :check_boxes, :collection => your_collection

Rails - Easy way to display all fields in view

OK I'm sure I'm missing something here, but please forgive me I'm new to Rails.
Is there some way in Rails to display all the fields for an object rather than specifying each?
In my show.html template rather than going
<p>Name: <%=h #user.full_name %></p>
<p>Email: <%=h #user.email %></p>
I just want a oneliner to do this without having to type out each of the 15 or so fields I have.
Its an admin page so its fine if all the fields are shown (id, created_at, etc.)
If this was PHP it would take me about 5 secs using foreach, but I've googled (on the wrong things obviously) for an hour with no luck.
Thanks!
Something like
<% for attribute in #user.attributes.keys %>
<p><%= attribute.humanize %> <%= #user.attributes[attribute].to_s %></p>
<% end %>
could do the trick.
Matt
I suppose you want to display all attributes of a row from database table which is defined as ActiveRecord model. You can use class method column_names (every ActiveRecord model has it), which returns names of table columns in an array.
<%= User.column_names.collect { |col_name| "#{col_name.capitalize}: <p>#{#user[col_name]}</p>" }.join("\n") %>
<%= debug #user %>
simple way to show the object... that is what I usually use anyway!
#user.attributes.each{|key, value| puts "#{key} : #{value}"}
This is the snippet I used to blacklist some attributes I didn't want to show...
controller (user_controller.rb)
def show
keys_blacklist = %W(user_id name) #these are the fields to hide
#user_showlist = #user.attributes.except(*keys_blacklist)
end
view (show.html.erb):
<!-- language: ruby --><% for attribute in #user_showlist.keys %>
<b><%= attribute.humanize %></b>
<%= #user.attributes[attribute].to_s %>
<!-- language: ruby --><% end %>
You can also use instead:
#user_showlist = #user.attributes.slice(*keys_whitelist)
in order to display a whilelist of properties.
If you are using haml and want to loop through the attributes on for example a user object in a view:
- for attribute in #user.attributes.keys
%p
= attribute.humanize
= #user.attributes[attribute].to_s

How can I create a form in Rails without having to use form_for and a model instance?

First of all, I'm a Rails newbie. I can hold my own in Ruby, but Rails is a whole different story for me. I like the development speed Rails offers me, but I can't seem to make peace with the existing documentation.
For all of my forms so far, I used form_for, with an instance for the model I needed to create ( for example, submitting a new book ). I would really like to be able to just write something like :
<% form(:action => "whatever") %>
<% text_field ... %>
<% file_field ... %>
<% end %>
From the articles I read online, I understood that this was the way things got done in Rails < 2.0 . Is there anyway of doing this in Rails > 2.0, or something equivalent to it ? Can you please post a snippet ?
Take a look at form_tag.
<% form_tag '/posts' do %>
<div><%= submit_tag 'Save' %></div>
<% end %>

Resources