Rails 3 date field is blank after form submit - ruby-on-rails

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.

Related

How to add address to users with Google map and jt-rails-address?

I'm new on rails. I work on a project, and I try to add physical address to my users. I want that the address can be help-complete with Google map for later exploitation. I find the jt-rails-address which look like perfect for my project. But I can't implement it. I need complete address (street, zip code, city & country).
add_address_to_users.rb :
class AddAddressToUsers < ActiveRecord::Migration[5.1]
def change
add_column :users, :address, :address
end
end
form edit.html.erb :
<div class="col-md-6 col-md-offset-3">
<%= form_for (#user), :html => { :multipart => true } do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :phone, "Téléphone :" %>
<%= f.phone_field :phone, class: 'form-control' %>
<%= f.label :address, "Addresse :" %>
<div class="jt-address-autocomplete">
<!-- This field is used to search the address on Google Maps -->
<%= f.text_field :address, class: 'jt-address-search' %>
<!-- All fields are hidden because the javascript will set their value automatically -->
<% for attr in JT::Rails::Address.fields %>
<%= f.hidden_field "address_#{street}", class: "jt-address-field-#{street}" %>
<% end %>
<% for attr in JT::Rails::Address.fields %>
<%= f.hidden_field "address_#{zip_code}", class: "jt-address-field-#{zip_code}" %>
<% end %>
<% for attr in JT::Rails::Address.fields %>
<%= f.hidden_field "address_#{city}", class: "jt-address-field-#{city}" %>
<% end %>
<% for attr in JT::Rails::Address.fields %>
<%= f.hidden_field "address_#{country}", class: "jt-address-field-#{country}" %>
<% end %>
</div>
<%= f.submit "Enregistrer les changements", class: "btn btn-primary" %>
<% end %>
</div>
application.js :
// This function is call when Google Maps is loaded
window.googleMapInitialize = function(){
// Simple usage
$('.jt-address-autocomplete').jt_address();
};
I have already put :address in my user_params in the users controller and has_address :address in the user model
I also have put my Google Api.
My actual error:
undefined local variable or method `street' for #<#Class:0x00007fe91ec7f768:0x00007fe91dfaefc0>
Thanks in advance for your help.
No more error but a bug, maybe because of Google Map, I don't know how
to resolve it, I can't write the address and there is an error message:
problem
Here the code of the inspector:
First, you should add fields like in documentation or scope them using select, now you have code that will create duplicated hidden fields.
You should check from rails console that method address is available on User instance of model.` Maybe you forgot to run migration or didn't restart server after installing this gem as this is js gem and will need restart.
Hope this answers your questions. Add comment to this answer if problem is still there.

Rails 4: text_field for acts_as_taggable_on not separating tags with a comma

I am trying to get the text_field in my form partial to comma-separate acts_as_taggable_on tags. Right now, when I reload the page, the commas disappear so if a field has two or more tags, they become one big tag instead. For instance, I get "Tag1 Tag2 Tag3" instead of "Tag1, Tag2, Tag3". I am using acts-as-taggable-on 3.4.2.
Here is my _form.html.erb partial:
<h2>Tags:</h2>
<p>Please separate the tags with a comma ','</p>
<% #article.tag_types.each do |tag| %>
<div class="form-group">
<strong><%= label_tag tag.to_s.titleize %></strong><br />
<%= f.text_field "#{tag.to_s.singularize}_list".to_sym, :placeholder => "Comma-separated list of #{tag.to_s}", class: 'form-control' %>
</div>
<% end %>
Every time I reload the edit page, the input value somehow removes the commas from the already-present tags, so the text field looks like this:
<input id="article_country_list" class="form-control" type="text" name="article[country_list]" value="China U.S.A." placeholder="Comma-separated list of countries">
instead of having value="China, U.S.A." as it should be.
Here is my model, article.rb:
class Article < ActiveRecord::Base
acts_as_taggable_on :people, :cities, :countries, :other
end
Any help would be much appreciated :)
Thanks!
Apparently this is a new security feature.
I solved the comma separation issue by doing:
<% #article.tag_types.each do |tag| %>
<div class="form-group">
<strong><%= f.label tag.to_s.titleize %></strong><br />
<% tag_sym = "#{tag.to_s.singularize}_list".to_sym %>
<% tag_list = "#{tag.to_s.singularize}_list" %>
<%= f.text_field tag_sym, value: #article.send(tag_list).to_s, :placeholder => "Comma-separated list of #{tag.to_s}", class: 'form-control' %>
</div>
<% end %>
Thanks! Since I am using ActiveAdmin with Formtastic I made a custom input.
So I created a new class: app/inputs/tag_list_input.rb with:
class TagListInput < Formtastic::Inputs::StringInput
def input_html_options
super.merge(:value => "#{#object.send(method).to_s.html_safe}")
end
end
and using this like:
f.input :some_tag_list, :as => :tag_list, :label => "SomeTags"

Problems using form helpers in ruby on rails

I have a class activity that has the follow atributes:
String type, Date date, String title
By including the associations it also has user_id and place_id.
class Activity < ActiveRecord::Base
belongs_to :user
belongs_to :place
In the other side User has many activities and place has many activities
So, the problem is when I want to create a new activity:
Scaffold creates the helper _form :
<%= form_for(#activity) do |f| %>
<% if #activity.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#activity.errors.count, "error") %> prohibited this activity from being saved:</h2>
<ul>
<% #activity.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :type %><br>
<%= f.text_field :type %>
</div>
<div class="field">
<%= f.label :date %><br>
<%= f.datetime_select :date %>
</div>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :user_id %><br>
<%= f.number_field :user_id %>
</div>
<div class="field">
<%= f.label :place_id %><br>
<%= f.number_field :place_id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I want to receive the first 3 fields from the form (type, date and title) but to associate a user and a place I have to do other way. I need the user that is actual logged in and the place is choosen by tiping the name.
My idea to do this is the following:
1) The user issue, I can make a query by using the current_logged_user that I have acess and get his ID.
2) The place issue, I can use the name that I receive from form and query my Places table for the place with the name X and get the ID after.
But, because I don't know too much about rails, how can I do this? How can I use f.text_field and then made the query or whatever and use after in the controller?
Controller has already this stuff :
def create
#activity = Activity.new(activity_params)
(...)
private
# Use callbacks to share common setup or constraints between actions.
def set_activity
#activity = Activity.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def activity_params
params.require(:activity).permit(:type, :date, :title, :user_id, :place_id)
end
You can structure your rails app to get neither the user_id nor the place_id directly from the form. Especially getting user_id from a submitted form is generally not a good idea. You usually do not want to whitelist user_id at all.
For user_id:
If you are using a gem like devise for user authentication, it gives you access to a method called current_user, which you can use to set the user_id from.
For place_id:
I suggest putting the activity as a sub route of place. e.g. instead of having the form under <host>/activities/new, put it under ``/places/:place_id/activities/new`. In your route file put the route as follows:
resources :places do
resources :activities
end
Now, in your controller action you can do the following:
def create
#activity = current_user.activities.new(activity_params)
#activity.place_id = params[:place_id] (or even safer will be #activity.place = Place.find(params[:place_id], but this will require one more sql query )
(...)
private
# Never trust parameters from the scary internet, only allow the white list through.
def activity_params
params.require(:activity).permit(:type, :date, :title)
end
UPDATE:
If you absolutely want to have the form under /activities/new route then you can have a select tag for place_id in your form:
select_tag 'activity[place_id]', options_from_collection_for_select(Place.all, 'id', 'name')
This will create a selection with name 'activity[place_id]' (named this way for params.require(:activity).permit(place_id) ) and options looking like
<option value="1">Barcelona</option>

Rails Migration Form Error With Id

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.

Ruby on rails drop down box Beginner lvl

So I am a beginner in ROR, like I know it for a month (school assignment and we don't get a cursus we need to use 'google')
So I want a dropdown box with a list of all my cities. Then if I pick a city I need to save the city_id in my database together with the date. The code I have so far seem to work except when I click on save it says that city is empty (and it can't be empty because of the failsave)
this is my code
<div class="field">
<%= f.label :stad_id %><br />
<% cities_array = Stad.all.map { |stad| [stad.naam, stad.land] } %>
<%= select_tag(Stad, options_for_select(cities_array)) %>
</div>
<div class="field">
<%= f.label :datum %><br />
<% datum = Time.now.to_s(:db) %>
<%= f.text_field :datum, :value => datum.inspect, :readonly => true %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I don't really know what I am doing wrong except I have an eery feeling I don't actually give the command to save it.
help is much thanked
sincerely
Robin
There are a few things I notice here that are wrong.
1) Put the creation of the cities_array into your controller, not in your view:
def edit
#something = Something.find(params[:id])
#cities_array = ... whatever ...
end
2) When creating your cities_array, you need to specify the ID of the city as the second parameter, like this:
#cities_array = Stad.all.map { |stad| [stad.naam, stad.id] }
3) The select_tag call isn't for Stad, it's for the model you're trying to save. For example, your form might look like this:
<%= form_for #something %>
<%= f.label :city %>
<%= f.select :city_id, #cities_array %>
# or!
<%= select :something, :city_id, #cities_array %>
<% end %>
I hoep this clears things up for you.

Resources