Rails Migration Form Error With Id - ruby-on-rails

I have just built a migration for my movies table called year_id
When I create two new years, 2012 and 2013, I then add the dropdown to select the year
and I get this:
How can i make my dropdown select show the actual year (2012 or 2013) and not #< Year:0x000 etc...
This is my model:
class Year < ActiveRecord::Base
attr_accessible :year
has_many :movies
end
This is my form:
<%= semantic_form_for #movie, :html => { :multipart => true } do |f| %>
<% if #movie.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#movie.errors.count, "error") %> prohibited this movie from being saved:
</h2>
<ul>
<% #movie.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field"> <%=h f.input :year, :include_blank => false %> </div><br />

Without seeing the full code for the form it is difficult to answer your question exactly. However, what is happening is the actual instance of your Year is being passed as the option text. You would probably see a similar output if you called to_s from the console
Year.first.to_s
# => "#<Year:0x00000101bcea10>"
Take a look at the options_for_select documentation at http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-options_for_select to see how to properly define a select element's options.
It looks like you might also be able to use the collection_select form helper to save yourself the trouble of defining the options array. It would look something like this
<%= f.collection_select :year_id, Year.all, :id, :year %>
The last option :year is the method that is used for the option text, so you'd change that to something meaningful for your model.

Related

change simple_form to form

hi i not long ago start to study rails
and in some screencast i saw that code strings:
<%= f.input :publish_date %>
<%= f.association :categories, :as => :check_boxes %>
and in out put i saw
3 fields for select ( year, months, day )
and
several checkboxes (as much as it was in the same name table)
in this video hero created new post
in migration => publish_date:date
in model => has_and_belongs_to_many :categories
and my question: help me change this form field(simple form) to normal view ( form_for )
Form Helper version of your inputs are:
<%= f.select_date :publish_date %>
<% Category.all.each do |category| %>
<%= check_box_tag 'video[category_ids][]', category.id %>
<%= category.name -%>
<% end %>

Rails metasearch search_form with checkboxes

I am a little confused.
Despite all questions around this theme here, I can't find the right solution.
What I want to do is to simply add check-boxes to my index filter form.
I am using Metasearch gem and here is my current code :
<form class="filter_form">
<%= form_for #search do |f| %>
<%= f.collection_select :categories_id_equals, Category.all, :id, :name, :include_blank => true, :prompt => "All categories" %>
<%= f.collection_select :location_id_equals, Location.all, :id, :name, :include_blank => true, :prompt => "All locations" %>
<ul>
<b> Type </b>
<% Type.all.each do |type|%>
<li>
<%= check_box_tag :types_id_equals, type.id %>
<%=h type.name %>
</li>
<% end %>
</ul>
<%= submit_tag "Find Now", :class => "find" %>
<% end %>
All works fine, except the checkboxes.
I don't have much experience in rails, so I don't really see what I am doing wrong and what could be the most convenient and simplest way.
Update
.....................
More explanation - I have a model Trips, which has HABTM relationship with two models (
Categories, Types) and belongs to Location.
I want to be able to filter Trips on it's index by categories (f.collection select) ,location (f.collection select) and types (checkboxes).
After checking types and submitting - nothing changes, no filtering is done!
<%= check_box_tag "type_ids[]", type.id %>
Will do it for you. The selected ids will be transfered as a string seperated by commatas. You can find them in params[:type_ids] but you have to deal with them manually! Rails is not a magican, its a framework.
Here's how I handled it.
<% #sub_categories.each do |cat| %>
<h2><%= cat.name %> <%= check_box_tag "q[product_category_id_in][]", cat.id %></h2>
<% end %>
Basically just q is whatever your query param is, then right after that in brackets sub in your meta_search method. I used whatever_foreign_key_in since I want to be able to add more than one id to the array to search on. Then add empty brackets after it so rails handles the post params correctly.

rails 3 has_many :through Form with checkboxes

Asked similar before.
Rails 3 has_many :through Form
But can't get the relationship with employmentships to be created from the users form.
Have read http://www.justinball.com/2008/07/03/checkbox-list-in-ruby-on-rails-using-habtm/
and http://millarian.com/programming/ruby-on-rails/quick-tip-has_many-through-checkboxes/ (which I was really hoping that it worked.)
Form submits, but only creates a blank record in employmentship.
<%= form_for #user do |f| %>
...
<p>
<% Company.all.each do |company| %>
<%= check_box_tag :company_ids, company.id, #user.companies.include?(company), :name => 'user[company_ids][]' -%>
<%= label_tag :companies_ids, company.id %>
<% end %>
</p>
<p><%= f.submit %></p>
<% end %>
Include a hidden field tag in the form to make sure something gets submitted when none of the check boxes are selected. This should work, after the <%end%>:
<%= hidden_field_tag "user[company_ids][]" %>
I may be wrong, but I think that the first arg of the check_box_tag function is the actual name of the input, so instead of
check_box_tag :company_ids, company.id, #user.companies.include?(company), :name => 'user[company_ids]'
you could try something like
check_box_tag 'user[company_ids]', company.id, #user.company_ids.include?(company.id)
Let me know if it works!

Rails 3 date field is blank after form submit

Rails newbie here.
I have 2 models: Target and Observation
Target works fine. I generated scaffolding for Observation, like this:
rails generate scaffold Observation date:date target:references
So app/models/observation.rb says:
class Observation < ActiveRecord::Base
belongs_to :target
end
Then I edited app/models/target.rb:
class Target < ActiveRecord::Base
has_many :observations
end
The scaffolding created app/views/observations/_form.html.erb which includes:
<div class="field">
<%= f.label :target %><br />
<%= f.text_field :target %>
</div>
And app/controllers/observation_controller.rb which includes:
def create
#observation = Observation.new(params[:observation])
I then go to create a new Observation. I enter a date and the ID of a target in the target field. When I submit, I get this error in the browser:
ActiveRecord::AssociationTypeMismatch in ObservationsController#create
Target(#2190392620) expected, got String(#2148287480)
Seems like the scaffolding would set up something that would work. But the error makes sense. It's receiving the ID of the Target instead of the Target itself. So I edited app/controllers/observation_controller.rb to say:
def create
#target = Target.find(params[:observation][:target])
#observation = #target.observations.create(:date => params[:observation][:date])
Now it creates the Observation record, with the reference to the Target. But the date field is blank.
I realize this may be a dumb newbie or RTFM question, but I'd really appreciate a pointer in the right direction. Thanks.
Here's the full contents of the form, after changing it to reflect the answer received.
<%= form_for(#observation) do |f| %>
<% if #observation.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#observation.errors.count, "error") %> prohibited this observation from being saved:</h2>
<ul>
<% #observation.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :date %><br />
<%= f.date_select :date %>
</div>
<div class="field">
<%= f.label :target %><br />
<%= f.collection_select :target_id, Target.all, :id, :name %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
change
<%= f.text_field :target %>
to
<%= f.text_field :target_id %>
And really better is to use something like select for this thing. Like:
<%= f.collection_select :target_id, Target.all, :id, :title %>
UPD
As far as date_select helper set not ordinary banch of variables for each element (year, month, day) you shoul do this:
date = [ params[:observation]['date(1i)'], params[:observation]['date(2i)'], params[:observation]['date(3i)'] ].join(".")
#observation = #target.observations.create(:date => date)
Actually just look into HTML source and you'll see it
(Not sure if you are still monitoring this, OP? For the benefit of everyone coming here via Google:)
There will be no params[:observation][:date] because dates are entered using several HTML input fields, and then magically merged in assignment. The keyword for this is "multi-parameter attributes", and this is the best explanation I've found:
How do ruby on rails multi parameter attributes *really* work (datetime_select)
I also wonder if this simpler snippet would work.
#observation = #target.observations.create(params[:observation])
You can use:
<%= collection_select(:observation, :target_id, Target.all, :id, :title %>
i think it will help you.

Multiple forms for the same model in a single page

On the front page of my rap lyrics explanation site, there's a place where users can try explaining a challenging line:
alt text http://dl.dropbox.com/u/2792776/screenshots/2010-02-06_1620.png
Here's the partial I use to generate this:
<div class="stand_alone annotation" data-id="<%= annotation.id %>">
<%= song_link(annotation.song, :class => :title) %>
<span class="needs_exegesis"><%= annotation.referent.strip.gsub(/\n/, "\n <br />") %></span>
<% form_for Feedback.new(:annotation_id => annotation.id, :created_by_id => current_user.try(:id), :email_address => current_user.try(:email)), :url => feedback_index_path, :live_validations => true do |f| %>
<%= f.hidden_field :annotation_id %>
<%= f.hidden_field :created_by_id %>
<p style="margin-top: 1em">
<%= f.text_area :body, :rows => 4, :style => 'width:96%', :example_text => "Enter your explanation" %>
</p>
<p>
<% if current_user %>
<%= f.hidden_field :email_address %>
<% else %>
<%= f.text_field :email_address, :example_text => "Your email address" %>
<% end %>
<%= f.submit "Submit", :class => :button, :style => 'margin-left: .1em;' %>
</p>
<% end %>
</div>
However, putting more than one of these on a single page is problematic because Rails automatically gives each form an ID of new_feedback, and each field an ID like feedback_body (leading to name collisions)
Obviously I could add something like :id => '' to the form and all its fields, but this seems a tad repetitive. What's the best way to do this?
If you don't want to change your input names or your model structure, you can use the id option to make your form ID unique and the namespace option to make your input IDs unique:
<%= form_for Feedback.new(...),
id: "annotation_#{annotation.id}_feedback"
namespace: "annotation_#{annotation.id}" do |f| %>
That way our form ID is unique, i.e. annotation_2_feedback and this will also add a prefix, e.g. annotation_2_, to every input created through f.
Did you consider nested_attributes for rails models? Instead of having multiple new feedback forms where each is tied to an annotation, you could have multiple edit annotation forms where each annotation includes fields for a new feedback. The id's of the generated forms would include the annotations id such as edit_annotation_16.
The annotation model would have a relationship to its feedbacks and will also accept nested attributes for them.
class Annotation < ActiveRecord::Base
has_many :feedbacks
accepts_nested_attributes_for :feedbacks
end
class Feedback < ActiveRecord::Base
belongs_to :annotation
end
You could then add as many forms as you want, one for each annotation. For example, this is what I tried:
<% form_for #a do |form| %>
Lyrics: <br />
<%= form.text_field :lyrics %><br />
<% form.fields_for :feedbacks do |feedback| %>
Feedback: <br/>
<%= feedback.text_field :response %><br />
<% end %>
<%= form.submit "Submit" %>
<% end %>
<% form_for #b do |form| %>
Lyrics: <br />
<%= form.text_field :lyrics %><br />
<% form.fields_for :feedbacks do |feedback| %>
Feedback: <br/>
<%= feedback.text_field :response %><br />
<% end %>
<%= form.submit "Submit" %>
<% end %>
And the quick and dirty controller for the above edit view:
class AnnotationsController < ApplicationController
def edit
#a = Annotation.find(1)
#a.feedbacks.build
#b = Annotation.find(2)
#b.feedbacks.build
end
def update
#annotation = Annotation.find(params[:id])
#annotation.update_attributes(params[:annotation])
#annotation.save!
render :index
end
end
I had this same issue on a site I'm currently working on and went with the solution you mention at the bottom. It's not repetitive if you generate the ID programmatically and put the whole form in a partial. For example, on my site, I have multiple "entries" per page, each of which has two voting forms, one to vote up and one to vote down. The record ID for each entry is appended to the DOM ID of its vote forms to make it unique, like so (just shows the vote up button, the vote down button is similar):
<% form_for [entry, Vote.new], :html => { :id => 'new_up_vote_' + entry.id.to_s } do |f| -%>
<%= f.hidden_field :up_vote, :value => 1, :id => 'vote_up_vote_' + entry.id.to_s %>
<%= image_submit_tag('/images/icon_vote_up.png', :id => 'vote_up_vote_submit' + entry.id.to_s, :class => 'vote-button vote-up-button') %>
<% end -%>
I also had the same issue but wanted a more extensible solution than adding the ID to each field. Since we're already using the form_for ... |f| notation the trick is to change the name of the model and you get a new HTML ID prefix.
Using a variant of this method: http://www.dzone.com/snippets/create-classes-runtime (I removed the &block stuff)
I create a new model that is an exact copy of the model I want a second form for on the same page. Then use that new model to render the new form.
If the first form is using
#address = Address.new
then
create_class('AddressNew', Address)
#address_new = AddressNew.new
Your ID prefix will be 'address_new_' instead of 'address_' for the second form of the same model. When you read the form params you can create an Address model to put the values into.
For those stumbling here, looking for the solution for Rails 3.2 app, look at this question instead:
Rails: Using form_for multiple times (DOM ids)

Resources