Country selection for Ruby on Rails web form - ruby-on-rails-3

I want to include country selection select box in my Rails web form. How is it possible in Ruby on Rails? My form is like this
<%= form_for :User, :url => {:action => :create } do |f| %>
<div class="field">
<%= f.label :select_countries %><br />
<%= f.select(:countries, country_list) %>
</div>
<%= f.submit "Create" %>
<% end %>
What can I include in place of country_list?

My opinion is to seed the countries list in database.
Create a model country with field 'name'.
In app/models/country.rb
attr_accessible :name
Load the list of country from the YAML file and seed into the database.
In config/country.yml
-
name: India
name: Pakistan
name: Cuba
#add required country name
In db/seed.rb
COUNTRIES = YAML.load_file(Rails.root.join('config/country.yml'))
COUNTRIES.each do |country|
Country.create(country)
end
Run
rake db:seed
Add country_id field in your user model(Write a migration to add field).
In app/models/user.rb
class User < ActiveRecord::Base
#associate user with country
belongs_to :country
end
In your new user form add the below code.
<%= f.select :country_id, Country.all.collect { |country| [country.name, country.id] },
{ :prompt => "Select Country" } %>

<%= f.country_select :country, ["United States"] %>
It really works for country_select gem

Rails used to provide a country select feature in the past. The feature has been extracted out from core and it's now packaged into the country_select plugin.
Use the plugin to enable the feature.

Related

undefined method `collection_check_boxes'

I'm trying to make an invoicing app. The form to create an invoice should include a collection of check boxes so the user can choose which lessons to invoice, but I'm getting this error: undefined method 'collection_check_boxes'.
Here are the models involved:
class Lesson < ActiveRecord::Base
attr_accessible :lesson_time, :lesson_date, :invoice_id
belongs_to :invoice
end
class Invoice < ActiveRecord::Base
attr_accessible :amount, :due_date
has_many :lessons
end
And the view:
<%= form_for(#invoice) do |f| %>
<fieldset>
<%= f.label :lessons %>
<%= f.collection_check_boxes(:lessons, Lesson.all, :id, :lesson_date) %>
<%= f.submit %>
</fieldset>
<% end %>
collection_check_boxes is not a method of form_builder. Either put:
<%= collection_check_boxes(:lessons, Lesson.all, :id, :lesson_date) %>
This will generate html which won't associate with your model (you won't be able to use MyModel.new(params[my_model]) and expect to get proper response. You would either have to manually call my_model.lessons = params[:lessons] or you can pass a html name parameter to conform your check box name to rails convention).
Or, if you are using formtastic as you tagged it, you can use this:
<%= f.input :lessons, :as => :check_boxes, :collection => Lesson.all %>
I suspect that since you tagged your post ruby-on-rails-3, you might be trying to use a rails 4 method inside a rails 3 project.
http://makandracards.com/makandra/32147-rails-4-introduced-collection_check_boxes
You'll likely need to use good old check_box_tag instead.

Append/Update params to an existing form using form_for

Fairly new to rails, meaning I believe I have most of the basics down, but definitely still a student of the art.
What I'm trying to accomplish: append params to an existing form using form_for.
So, I need to find the id for an existing form and pass a new hash to this form using the JobsController to append several columns of data.
Steps are to select the job number from a select_box, add any changes/notes for that job using text_fields/check_boxes, then submit. Also view used is a partial, found in views/jobs.
Current problem, despite several attempts, is:
Overriding the default 'post' method --tried several combinations of the following: method => 'put', :action => update, :controller => :jobs
class Job < ActiveRecord::Base
attr_accessible :note, :twgid, :padd, :lnkbr, :txtwr, :datewr, :pinmiss, :headch, :name, :nucopy, :minrend, :majrend, :lnkwr, :gmail, :hotmail, :aol, :outlook, :note, :linkwr
belongs_to :form
end
JobsController:
( scaffolded )
View: (jobs/_form.html.erb)
<%= form_for #job do |f| %>
<fieldset>
<div class="form-horizontal">
<div class="control-group">
<span class="control-label">
<%= f.label :name, "TWGID" %></span>
<%= f.select :name, options_from_collection_for_select(Job.all, :name, :name), :prompt => 'Select' %>
</fieldset>
<fieldset>
<div class="control-group">
<span class="control-label">
<%= f.label :padd, "Add Padding?" %></span>
<%= f.check_box :padd %>
<%= f.hidden_field, :updated, :value => '1' %>
<% end %>
##Routes##
get 'signup', to: 'users#new', as: 'signup'
get 'login', to: 'sessions#new', as: 'login'
get 'logout', to: 'sessions#destroy', as: 'logout'
resources :sessions
resources :users
resources :forms
resources :projects
resources :jobs
root :to => 'forms#index'
I'm not 100% sure what your trying to do but let me take a crack at it.
Well, the first thing I see is that in update_job on the first line you try grabbing a Change object and putting it into #change. The problem is that your using #change.id which obviously hasn't been set yet. If you are getting the id through params you will want to use:
#change = Change.find(params[:id])
Second, you are trying to update an attribute of Job but have a Change object. This will not work.
What I think your trying to do overall is to build a form that updates a change and will also update its associations (jobs in this case). A quick link on how to do this is here:
Form Helpers <--- Search for Nested Attributes Examples
Here is the code I would suggest:
<%= form_for #change do |f| %>
<%= f.fields_for :job do |j| %>
Updated : <%= j.check_box :updated %>
<% end %>
<% end %>
This will put the updated option in params[:change][:jobs_attributes] and when you send params[:change] into your update like so, #change.update_attributes(params[:change]) it will update your job as well.

Rails simple_form grouped collection not working

In my Rails app, I'm using simple_form.
I'm trying to use grouped collection selects.
Without simple_form, this works:
<%= f.label :employee_id, "Lead3:" %>
<%= f.grouped_collection_select :employee_id, Workgroup.order(:id) , :employees, :group, :id, :employee_full_name %>
But, my simple_form attempt doesn't - the dropdown is empty:
<%= f.input :employee, collection: #workgroups, as: :grouped_select, group_method: :employees, :label => 'Lead2:' %>
OR
<%= f.association :employee, collection: #workgroups, as: :grouped_select, group_method: :employees, :label => 'Lead2:' %>
I would suggest to check your #workgroups definition in the controller. It probably returns nil or is not specified. Depending on what action calls your form, you should have something like this:
#workgroups = Workgroup.all(order: id)

Multi-page Multi-Model Form in Rails

I'm trying to create a multi-page form that uses multiple models. I have an applicant and this applicant has more than one address (one to many relationship).
I would like the first page to contain information about the applicant, and then the page after that to have the form for the address(es)
This is what I have at the moment:
applicant.rb
has_many :addresses, :dependent => :destroy
accepts_nested_attributes_for :addresses
address.rb
belongs_to :applicant
applicants_controller.rb:
def new
session[:applicant_params] ||= {}
#applicant = Applicant.new(session[:applicant_params])
2.times do
#addresses=#applicant.addresses.build
end
session[:address_params] = #addresses.attributes
end
def create
session[:applicant_params].deep_merge!(params[:applicant]) if params[:applicant]
session[:address_params] ||= params[:address]
#applicant = Applicant.new( session[:applicant_params] )
#applicant.addresses.new(session[:address_params])
if params[:forward_button] or params[:back_button]
#applicant.current_step = session[:applicant_step]
if params[:back_button]
#applicant.previous_step
else
#applicant.next_step
end
session[:applicant_step]=#applicant.current_step
render "new"
else
.....
In the new view:
<%= form_for #applicant do |f| %>
<%= render "#{#applicant.current_step}_step", :f => f %>
<p><%= f.submit "Continue", :name => "forward_button" unless #applicant.last_step? %> </p>
<p><%= f.submit "Back", :name => "back_button" unless #applicant.first_step? %></p>
<% end %>
#applicant.current_step will be either address_step or applicant_step, and these are below:
_applicant_step.html.erb
<div class="field">
<%= f.label :first_name %><br />
<%= f.text_field :first_name ,:width=>'10px', :size=>"20", :maxlength=>"20" %>
</div>
<div class="field">
<%= f.label :middle_name %><br />
<%= f.text_field :middle_name %>
</div>
....
_address_step.html.erb
<%= f.fields_for :addresses do |u| %>
<div class="field">
<%= u.label :address %><br />
<%= u.text_area :address , :cols=> 20, :rows=>5%>
</div>
<div class="field">
<%= u.label :telephone, "Telephone Number" %><br />
<%= u.text_field :telephone %>
</div>
...
And that's it. Now the problem I have is as follows, I want to save the address information as well as the applicant information. And I thought just by saying: #applicant.addresses.new then they will be included in the session information of the applicant, but they weren't (when I got the the address page, there were no fields!). So I created a new session variable to hold the address information. But I have a problem. Everytime I go from one page to the other (in the create action) a new address field (with all its attributes) is created and added to the form. So first I have one address, then I have 2 and so on. Am I going about this the wrong way? How can I have a multi-page form, with multiple models (that are related), and when going from one page to the next the data is not erased.. Until I eventually reach the last page where I could submit (and save) all the models..
I would be grateful if anyone could help..
Thank you.
You can certainly get this working, but (depending on the number of steps you need), it could get pretty convoluted.
Have you considered using a single new and create request on the server side, and using Javascript to break up the form into multiple steps on the client side? It seems like this could be a lot simpler. Your Rails application will behave more like a standard REST application, and you can break this up however you see fit on the client side.
I have not used it myself, but a jQuery plugin such as this one should do the trick:
http://thecodemine.org/

Can't mass-assign protected attributes:

I have pulled out all my hair. No more left... :(
I am using Spree 0.3.4, within an extension I need to register some retailers up. so I direct them to a retailers form which has many custom fields which belong to a retailer model...
So I am trying to validate/submit all the fields from one form like so
myextension/app/views/user_registrations/new.html.erb
<%= form_for (:user, :url => registration_path(#user, :type => "retailer) do |f| %>
<%= f.fields_for :retailer do |r| %>
<%= r.text_field :name %>
<% end %>
<%= f.text_field :email %>
<% end %>
etc etc
class Retailer < ActiveRecord::Base
belongs_to :user
validates :name,
:presence => true
end
class User < ActiveRecord::Base
has_one :retailer
accepts_nested_attributes_for :retailer
attr_accessible :retailer_attributes
# theres a whole lot more spree and devise stuff here. not sure worth mentioning
end
I have also added the abilities in the cancan ability.rb
The problem is the retailer feilds never get validated and the data is never inserted into the database...
I created a blank app, and tried this process from scratch with some plain old scaffolding and it works fine.
any ideas??
In your application helper, do something like this(assuming your have Ruby 1.9.* for the tap functionality, otherwise checkout rails returning here):
def setup_user(user)
user.tap do |u|
u.build_retailer if u.retailer.nil?
end
end
then in your view change it to this:
<%= form_for (setup_user(#user), :url => registration_path(#user, :type => "retailer) do |f| %>
See if that works.