How to fix Country-State-Select gem undefined method issue? - ruby-on-rails

In a implementation of gem: https://github.com/arvindvyas/Country-State-Select
When i go to Post Job new page show this error on the log
undefined method `country' for #<Job:0x007f8c07092320>
I've tried to put the
accepts_nested_attributes_for
in the job model, but did not worked.
Someone have any hint to spare?
Job Model
class Job < ActiveRecord::Base
belongs_to :user
belongs_to :location
accepts_nested_attributes_for :location, allow_destroy: true
default_scope -> { order(created_at: :desc) }
end
Location Model
class Location < ActiveRecord::Base
has_many :users
has_many :jobs
end
Job new view
<%= simple_form_for #job do |f| %>
<%= f.simple_fields_for :location do |l| %>
<%= l.input :country, label: "Country", collection: CountryStateSelect.countries_collection %>
<%= l.input :state, CountryStateSelect.state_options(label: "State / Province", form: f, field_names: { :country => :country, :state => :state } ) %>
<%= l.input :city, CountryStateSelect.city_options(label: "City ", form: f, field_names: { :state => :state, :city => :city } ) %>
<% end %>
<%= f.input :name, label: 'Name', error: 'Name is mandatory' %>
<%= f.input :description, placeholder: 'user#domain.com' %>
<%= f.button :submit %>
<% end %>

In the fields
<%= l.input :state, CountryStateSelect.state_options(label: "State / Province", form: f, field_names: { :country => :country, :state => :state } ) %>
<%= l.input :city, CountryStateSelect.city_options(label: "City ", form: f, field_names: { :state => :state, :city => :city } ) %>
you have form: f, but you are within a simple_fields_for block which is currently using l instead of f

Looks like you're missing a country field in your Job model. Add it using a migration:
add_column :jobs, :country, :string

Related

Ruby on Rails | one form - three tables (can't save the form content)

I am trying to write an app - simple form for user's details which saves data to three different tables (1.users, 2.companies, 3.adresses).
I have set some assosiations using belongs_to and has_many, and also use nested_attributes and fields_for to build one form. But I can't save data.
I am a newbie, so probably I'm making some stupid mistakes, but I cannot really find them since 3 days. Also tried to look in google and here, among forum posts, but didn't find a code, where the problem was connected with child class. My assosiations between user, company and adress are quite weird. Can anyone help me?
Here is my form:
<%= simple_form_for #user do |f| %>
<h5>Personal Details</h5>
<%= f.input :firstname, label: 'Your First Name:' %>
<%= f.input :lastname, label: 'Your Last Name:' %>
<%= f.input :email, label: 'Your Email:' %>
<%= f.input :dateofbirth, label: 'Your Date of Birth:' %>
<%= f.input :phonenumber, label: 'Your Phone Number' %>
<h5>Adress</h5>
<%= f.fields_for :adresses do |g| %>
<%= g.input :street, label: 'Street:' %>
<%= g.input :city, label: 'City:' %>
<%= g.input :zipcode, label: 'Zip Code:' %>
<%= g.input :country, label: 'Country:' %>
<% end %>
<h5>Company</h5>
<%= f.fields_for :companies do |h| %>
<%= h.input :name, label: 'Name:' %>
<% end %>
<%= f.fields_for :adresses do |i| %>
<%= i.input :comstreet, label: 'Street:' %>
<%= i.input :comcity, label: 'City:' %>
<%= i.input :comzipcode, label: 'Zip Code:' %>
<%= i.input :comcountry, label: 'Country:' %>
<% end %>
<%= f.button :submit %>
<% end %>
user.rb
class User < ApplicationRecord
belongs_to :company, inverse_of: :users
belongs_to :adress, inverse_of: :users
validates_presence_of :firstname, :lastname, :email
validates_length_of :firstname, :maximum => 100
validates_length_of :lastname, :maximum => 100
end
company.rb
class Company < ApplicationRecord
has_many :users, inverse_of: :companies
belongs_to :adress, inverse_of: :companies
accepts_nested_attributes_for :users
end
adress.rb
class Adress < ApplicationRecord
has_many :users, inverse_of: :adresses
has_many :companies, inverse_of: :adresses
accepts_nested_attributes_for :users, :companies
end
users_controller
class UsersController < ApplicationController
def index
end
def new
#user = User.new
#company = Company.new
#adress = Adress.new
end
def create
#user = User.new(user_params)
if #user.save
redirect_to root_path
end
end
private
def user_params
params.require(:user).permit(:firstname, :lastname, :email, :dateofbirth,
:phonenumber, company_attributes: [:name],
adress_attributes: [:street,:city, :zipcode, :country, :comstreet,
:comctiy, :comzipcode, :comcountry] )
end
end
In your user.rb file:
class User < ApplicationRecord
belongs_to :company, inverse_of: :users
belongs_to :adress, inverse_of: :users
validates_presence_of :firstname, :lastname, :email
validates_length_of :firstname, :maximum => 100
validates_length_of :lastname, :maximum => 100
# add nested attributes here not in other models
accepts_nested_attributes_for :companies
accepts_nested_attributes_for :addresses
end
Also, in your controller: carefully check the names of parameters passed. address_attributes misspelled
def user_params
params.require(:user).permit(:firstname, :lastname, :email, :dateofbirth,
:phonenumber, company_attributes: [:name],
address_attributes: [:street,:city, :zipcode, :country, :comstreet,
:comctiy, :comzipcode, :comcountry] )
end
In the view, remove multiple form elements for address. You wrote twice.
I have made few changes in the code and able to save the form, please check
Here is my form:
<%= simple_form_for #user do |f| %>
<h5>Personal Details</h5>
<%= f.input :firstname, label: 'Your First Name:' %>
<%= f.input :lastname, label: 'Your Last Name:' %>
<%= f.input :email, label: 'Your Email:' %>
<%= f.input :dateofbirth, label: 'Your Date of Birth:' %>
<%= f.input :phonenumber, label: 'Your Phone Number' %>
<h5>Adress</h5>
<%= f.fields_for :adress_attributes do |g| %>
<%= g.input :street, label: 'Street:' %>
<%= g.input :city, label: 'City:' %>
<%= g.input :zipcode, label: 'Zip Code:' %>
<%= g.input :country, label: 'Country:' %>
<% end %>
<h5>Company</h5>
<%= f.fields_for :company_attributes do |h| %>
<%= h.input :name, label: 'Name:' %>
<%= h.fields_for :adress_attributes do |i| %>
<%= i.input :street, label: 'Street:' %>
<%= i.input :city, label: 'City:' %>
<%= i.input :zipcode, label: 'Zip Code:' %>
<%= i.input :country, label: 'Country:' %>
<% end %>
<% end %>
<%= f.button :submit %>
<% end %>
user.rb
class User < ApplicationRecord
belongs_to :company, inverse_of: :users
belongs_to :adress, inverse_of: :users
validates_presence_of :firstname, :lastname, :email
validates_length_of :firstname, :maximum => 100
validates_length_of :lastname, :maximum => 100
accepts_nested_attributes_for :company
accepts_nested_attributes_for :address
end
company.rb
class Company < ApplicationRecord
has_many :users, inverse_of: :companies
belongs_to :adress, inverse_of: :companies
accepts_nested_attributes_for :users
accepts_nested_attributes_for :adress
end
adress.rb
class Adress < ApplicationRecord
has_many :users, inverse_of: :adresses
has_many :companies, inverse_of: :adresses
accepts_nested_attributes_for :users, :companies
end
users_controller
class UsersController < ApplicationController
def index
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
redirect_to root_path
end
end
private
def user_params
params.require(:user).permit(:firstname, :lastname, :email, :dateofbirth,
:phonenumber, company_attributes: [:name, adress_attributes: [:street,
:ctiy, :zipcode, :country]],
adress_attributes: [:street,:city, :zipcode, :country] )
end
end
It is working now and able to save user, address and company with company address.

rails Can't save serialized object in the database

I have a serialized object :address in Hotel class. When I'm trying to save data using the form, it all saves fine. All except :address. No errors, nothing... Tried different variants, please help.
Here is my code:
migrations
class CreateHotels < ActiveRecord::Migration
def change
create_table :hotels do |t|
t.string :title
t.integer :user_id
t.integer :stars
t.text :room
t.decimal :price
t.text :address
t.timestamps
end
add_index :hotels, [:user_id, :created_at]
end
end
hotel.rb
class Hotel < ActiveRecord::Base
belongs_to :user
default_scope -> { order('created_at DESC') }
validates :title, presence: true, length: { maximum: 80 }
validates :stars, presence: true
validates :room, length: { maximum: 800 }
validates :user_id, presence: true
serialize :address, Hash
end
new.html.erb
<%= form_for(#hotel) do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :stars %>
<%= f.text_field :stars %>
<%= f.label :room, "Room description" %>
<%= f.text_area :room, size: "20x10" %>
<%= f.label :price %>
<%= f.number_field :price %>
<%= f.fields_for :address, OpenStruct.new(f.object.address || {}) do |o| %>
<%= o.label :country %>
<%= o.text_field :country %>
<%= o.label :state %>
<%= o.text_field :state %>
<%= o.label :city %>
<%= o.text_field :city %>
<%= o.label :street %>
<%= o.text_field :street %>
<% end %>
<% end %>
In your hotels_controller.rb have you permitted address params?
params.require(:hotel).permit(address: [:country, :state, :city, :street])

Nested form undefined method `model_name'

I have nested forms dealing with 3 models. Job, Employer, User
The form on the jobs controller needs to create a job, employer and user.
The Job and Employer forms are working correctly, however when I add the User nested form I get the error "undefined method `model_name' for NilClass:Class"
I'm completely confused as to why.
Here is my code:
Job Model
attr_accessible :category, :employer_id, :employer_attributes, :user_attributes
belongs_to :employer
accepts_nested_attributes_for :employer, :user
has_many :applications
has_many :users, :through => :applications
Employer model
attr_accessible :companyname, :email, :logo, :password, :url
has_many :jobs
belongs_to :user
User Model
attr_accessible :admin, :cv, :name, :password, :website, :password_confirmation
has_many :applications
has_many :jobs, :through => :applications
has_one :employer
_form.html.erb
<%= form_for(#job) do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.fields_for :employer do |builder| %>
<%= builder.label :companyname, "Company Name" %>
<%= builder.text_field :companyname %>
<% end %>
<%= f.fields_for :user do |builder| %>
<%= builder.label :email, "Email" %>
<%= builder.text_field :email %>
<%= builder.label :password, "Password" %>
<%= builder.text_field :password %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Job Controller
def new
#job = Job.new
#job.employer = #job.build_employer
#job.user = #job.build_user
To doesn't look like your Job model has a user method. You may need to add
belongs_to :user

Rails 3.1+ Simple Nested Form validation and Twitter Bootstrap control states

I need some help with handling validations with Twitter Bootstrap properly. The validations are working properly, the issue is Twitter Bootstrap Flash screen. This is what I mean:
No fields filled out and submitted returns: http://i.stack.imgur.com/8pvUc.png
The 2 of the required 4 fields submitted returns: http://i.stack.imgur.com/J6lCi.png
(notice that it doesn't flash the errors)
I have a basketball app where a Player can be on many Rosters(for player roster archiving purposes) and a Roster can have many Players.
Roster.rb
class Roster < ActiveRecord::Base
belongs_to :team
has_many :rosterizes
has_many :players, :through => :rosterizes
accepts_nested_attributes_for :players
validates_presence_of :jersey_number, :class_year
attr_accessible :jersey_number, :class_year, :players, :team_id, :players_attributes
end
Rosterizes.rb(poorly named I know...)
class Rosterize < ActiveRecord::Base
belongs_to :player
belongs_to :roster
attr_accessible :player_id, :roster_id
end
Player.rb
class Player < ActiveRecord::Base
has_many :rosterizes
has_many :rosters, :through => :rosterizes
validates_presence_of :first_name, :last_name
attr_accessible :first_name, :last_name, :active
end
_add_player_form.html.erb
(nested form)
<%= simple_nested_form_for #roster, :url =>player_added_team_path, :html => { :class => 'form-horizontal' } do |f| %>
<%= f.simple_fields_for :players, #roster.players.build do |x| %>
<%= x.input :first_name %>
<%= x.input :last_name %>
<%= x.input :active, :as => :hidden, :input_html => {:value => true} %>
<%end%>
<%=f.input :class_year %>
<%=f.input :jersey_number %>
<%=f.input :team_id, :as => :hidden, :input_html => {:value => params[:id]}%>
<div class="well">
<%= f.button :submit, :class => 'btn-primary icon-plus-sign btn-success', :value => "Add To Team" %>
</div>
<%end%>
Thanks for the help in advance!
SOLUTION
My problem is that every time the view was loaded, it was building a new form, thus never getting back the errors on the rollback
I made a change to my controller that builds for the nested form
Controller
def add_player
...
#new_player = #roster.players.build
end
And made the change accordingly to the view
_add_player_form.html.erb
<%= f.simple_fields_for :players, #new_player do |x| %>
...
<%end%>
This did the trick, thanks Mober!
the reason why only the first level validation is shown an the associated not is fairly simple... You do a <%= f.simple_fields_for :players, #roster.players.build do |x| %> which buildes the association ALWAYS new when the sites's rendered. What you want to is building the association only if it does not exists yet...
<% #roster.players.build if !#roster.players %>
<%= f.simple_fields_for :player do |player_form| %>
...
<% end %>
Twitter Bootstrap doesn't actually validate anything, it just provides styling for validation classes (error, success, etc).
Now, I'm not a Ruby expert by any means but it looks like you are ending your form early:
<%= f.simple_fields_for :players, #roster.players.build do |x| %>
<%= x.input :first_name %>
<%= x.input :last_name %>
<%= x.input :active, :as => :hidden, :input_html => {:value => true} %>
<%end%> <---- here
<%=f.input :class_year %>
<%=f.input :jersey_number %>
<%=f.input :team_id, :as => :hidden, :input_html => {:value => params[:id]}%>
Should be this?
<%= f.simple_fields_for :players, #roster.players.build do |x| %>
<%= x.input :first_name %>
<%= x.input :last_name %>
<%= x.input :active, :as => :hidden, :input_html => {:value => true} %>
<%= f.input :class_year %>
<%= f.input :jersey_number %>
<%= f.input :team_id, :as => :hidden, :input_html => {:value => params[:id]}%>
<% end %>

Edit form load error using Formtastic, STI, Polymorphic & ActiveAdmin

I am new to rails and using a combination of formtastic, activeadmin,sti and polymorphic associations to build a form
When I I can create a nested form with the address parent with no problem, but when i introduce STI and attempt to build_origin_address instead of build_address, that is when I get the error below when loading the edit view
NameError in Admin/leads#edit
Showing .../app/views/admin/leads/_form.erb where line #3 raised:
uninitialized constant Lead::OriginAddress
Models:
class Address < ActiveRecord::Base
belongs_to :addressable, :polymorphic => true
belongs_to :lead
validates :line1, :presence => true, :length => {:minimum => 2}
attr_accessible :line1, :line2, :city, :state, :zip, :country
end
class OriginAddress < Address
end
class DestinationAddress < Address
end
class Lead < ActiveRecord::Base
has_one :origin_address, :dependent => :destroy, :as => :addressable
accepts_nested_attributes_for :origin_address, :allow_destroy => true
end
partial used in edit view:
<%= semantic_form_for [:admin, #lead] do |f| %>
<% #lead.build_origin_address unless #lead.origin_address %>
<%= f.inputs :name => "Lead Info" do %>
<%= f.input :first_name %>
<%= f.input :last_name %>
<% end %>
<%= f.semantic_fields_for :origin_address do |origin| %>
<%= origin.inputs :name => "Origin Address" do %>
<%= origin.input :line1 %>
....
<% end %>
<% end %>
<%= f.buttons do %>
<%= f.commit_button %>
<% end %>
<% end %>
I think you must define #lead before your form.

Resources