Rails checkboxes and serialized data - ruby-on-rails

I'm trying to figure out whats the best way to get checkboxes to properly show their current state. This is what I have in my form
<%= form_for #user, :url => user_notification_preferences_path(#user), :method => :put do |f| %>
<%= f.fields_for :notification_preferences, #user.notification_preferences do |p| %>
<%= p.check_box :notify_on_friend_post %>
<%= p.check_box :notify_on_friend_post %>
<%= p.check_box :notify_on_friend_request %>
<%= p.check_box :notify_on_friend_comment %>
<% end %>
<%= f.submit %>
<% end %>
notification_preferences is a serialized hash on my user model
class User < ActiveRecord::Base
serialize :notification_preferences, Hash
My issue that is no matter what I try, I can not get the check boxes to reflect the existing state of the hash values. IE, if the hash already contains :notify_on_friend_post => 1, then the check box for that value should be checked.
The form posts the data fine, and I'm able to update my model as well.
Update
using check_box_tag I can get this to work
<%= p.hidden_field :notify_on_friend_post, :value => "0" %>
<%= check_box_tag "user[notification_preferences][notify_on_friend_post]", "1", #user.notification_preferences[:notify_on_friend_post] == "1" ? true : false %>
ugly but working, still hoping I'm missing something very obvious

I ran into this problem and solved it in a simpler way.
<%= form_for #user do |f| %>
<%= f.fields_for :notifications, #user.notifications do |n| %>
<%= n.check_box :new_task, checked: #user.notifications[:new_task] == "1" %>
<% end %>
<%= f.submit %>
<% end %>
In this way you let the magic of check_box to the work and don't need to have a hidden_field because Rails will provide one for you. Still unsure why you need a "checked" field, but it seemed to not work without one.

Try something like this:
<%= form_for #user, :url => user_notification_preferences_path(#user), :method => :put do |f| %>
<%= check_box_tag "user[notification_preferences][]", :notify_on_friend_post, #user.notification_preferences.try(notify_on_friend_post) %>
<%= f.submit %>
<% end %>

Related

Displaying hstore saved values in form for input when editing

I got a problem with displaying saved values in form_for for hstore data (filters).
It's saved in database but when I'm going back to this view to edit something I can't see actual values in input form fields like in normal form_for without hashes.
This is shorcut of me view code
<%= form_for #lesson, url: { action: "step3" } do |f| %>
<%= f.fields_for :filters do |d| %>
<%= #lesson.filters["age_from"] %> # like this value would be displayed
<%= d.text_field :age_from %>
<%= d.text_field :age_to %>
<%= d.text_field :name %>
<%= link_to "Back", step1_lesson_path(#lesson) %>
<%= submit_tag "Next" %>
<%end%>
<%end%>
Thanks in advence
Can you try with changing the view a bit, passing #lesson.filters in fields_for as following
....
<%= f.fields_for :filters, OpenStruct.new(#lesson.filters) do |d| %>
#your code goes here ...
<% end %>
....
Solution without modifying controller action:
<%= f.fields_for :filters, OpenStruct.new(#lesson.filters) do |d| %>

Multiple fields not display in single form and model Rails

I have model product. I want to create multiple record in single model (product), but fields not display in view
#controller
#products = Array.new(3){ Product.new }
# view
<%= form_tag create_product_path, :method => :post, :class => "form-horizontal", 'role' => "form" do %>
<% #products.each_with_index do |product, index| %>
<% fields_for "products[#{index}]", product do |f| %>
<%= f.text_field :date %>
<%= f.text_field :name %>
<% end %>
<% end %>
<%= submit_tag "Submit", :class => "btn btn-primer" %>
Look at this screenshoot, fields not appear. Can anyone tell me, why new form method using array not appear?
Don't forget about <%= on fields_for
read about fields_for
rails 2.x - 3.0
<% fields_for "products[#{index}]", product do |f| %>
rails > 3.1.x
<%= fields_for "products[#{index}]", product do |f| %>

correct syntax for form_for url in rails

This is probably simple, I'm still coming to terms with rails syntax. What is the right syntax to pass the address_id in the url for form_for to a modified route?
This is the form - note the "address_id parameter"
<div class="one_fourth floatcenter">
<%= form_for address, :url => edit_address_path(:id => address.id), :method => :get do |f| %>
<%= content_tag(:button, :class => 'btn btn-inverse') do %> Edit Address
<% end %>
<% end %>
</div>
And this is the route I've configured:
get "edit_address/:id" => "member/addresses#edit"
Id is not being passed to the controller for some reason...
form_for address should be enough if address is a persisted object, but if it's not enough, then form_for address, url: edit_address_path(address) is what you want.
This is very simple. In place of url, you put your post method route:
<%= form_for(#post, url: super_posts_path) do |f| %>
...
<% end %>
You also call by action
<%= form_for #friend,:url=> { action: "create_friend"} do |f|%><br>
<%= f.label :u_from %>
<%= f.text_field :u_from %>
<%= f.label :u_to %>
<%= f.text_field :u_to %>
<%= f.submit%>
<% end %>

make boolean form field hidden

I have a boolean to make comments public or private.
The boolean is a column in submissions and I have it working in a clumsy way right now and would like to eliminate the checkbox from the form, replacing with a hidden field, so that all the user sees is the submit button, conditional based on the boolean state:
submissions#show:
<% if #submission.comment_show == true %>
<%= render "hide_comment_form" %>
<%= render "comments/comment" %>
<% else %>
<%= render "show_comment_form" %>
</div>
<% end %>
_show_comment_form
<%= simple_form_for [#contest, #submission] do |f| %>
<div>
<%= f.input :comment_show, label: false %>
<%= hidden_field_tag :contest_id, #contest.id %>
<%= f.submit "Make Comments Public", :class => 'btn btn-mini' %>
</div>
<% end %>
_hide_comment_form
<%= simple_form_for [#contest, #submission] do |f| %>
<div class ="">
<%= f.input :comment_show, label: false %>
<%= hidden_field_tag :contest_id, #contest.id %>
<%= f.submit "Make Comments Private", :class => 'btn btn-mini' %>
</div>
<% end %>
I have tried hidden_field_tag, but haven't had any luck getting it to work.
Also, I've seen some fancier methods and routing to accomplish the same thing:
http://buckybits.blogspot.com/2011/09/simple-ajax-property-toggle-in-rails-30.html
But I would prefer to use a hidden field and conditionals to keep it simple.
Is it possible to use a hidden field to set a boolean in a form or do I have to go with a custom method and routing?
See the answer to this SO question: rails simple_form - hidden field - create?
Since you are using simple form, you can do something like this:
f.input :contest_id, :as => :hidden, :input_html => { :value => #contest.id }

Nested Rails forms and using label_tag, checkbox_tag and other form_tag functions

In regular forms in Ruby on Rails, if using form_for to build a model, as the API docs state, form_for doesn't create an exclusive scope, and it's possible to use form_tag functions within the form_for form.
For example:
<% form_for :person, #person, :url => { :action => "update" } do |f| %>
First name: <%= f.text_field :first_name %>
Admin? : <%= check_box_tag "person[admin]", #person.company.admin? %>
<% end %>
However, in a nested form, the labels and fields have names that are automatically generated by Rails to be associated with a given nested model and not to overlap if multiple nested models are created at once. Is it possible to still use the form_tag functions?
I'd like to do something like this:
<% person_form.fields_for :children do |child_form| %>
Name: <%= child_form.text_field :name %>
Give up for Adoption?: <%= check_box_tag "adoption_" + child_form_index, false %>
<% end %>
However, I don't know how to get access to the child_form's index to ensure that check_box_tag has a unique value if there are multiple children.
Is what I'm trying to do possible?
See the docs for fields_for under one-to-many.
It looks to me like basically you can just use each (or each_with_index) and pass the block variable along with the symbol:
<% form_for #person, :url => { :action => "update" } do |person_form| %>
...
<% #person.children.each_with_index do |child, index| %>
<% person_form.fields_for :children, child do |children_fields| %>
Name: <%= children_fields.text_field :name %>
Give up for Adoption?: <%= check_box_tag "adoption_" + index, false %>
<% end %>
<% end %>
<% end %>
Of course, you'll have to handle the "offer for adoption" login on your own.

Resources