How to add a select without association to model? - ruby-on-rails-3

I have a model called "Store" and it has an attribute "City" which has a "State" associated to it. I'm creating a store's filter by state and/or city with simple_form. The problem is, how to make simple_form does not associate the "State" to "Store" ?
class State < ActiveRecord::Base
attr_accessible :name
has_many :cities
end
class City < ActiveRecord::Base
attr_accessible :name
belongs_to :state
has_many :stores
end
class Store < ActiveRecord::Base
attr_accessible :latitude, :longitude, :description, :city_id
validates :city, :presence => true
validates :description, :presence => true, :length => {:maximum => 500}
validates :latitude, :presence => true
validates :longitude, :presence => true
belongs_to :city
end
<%= simple_form_for #store, :html => { :class => 'add-store-form', :style => "display:none;" } do |f| %>
<table border="0">
<tr>
<td>Estado:</td>
<td>
<%= f.collection_select :state, State.all, :include_blank => false, :label => false,
:input_html => { :id => "state_id", :name => "state_id" } %>
</td>
</tr>
.
.
This way is not working.
How can I do this?
Thanks in advance!

This is not the answer to you question, but improve your code by doing:
validates :city, :latitude, :longitude, :description, presence: true
validates :description, length: {maximum: 500}
And I recommend using Strong Parameters (Default in rails 4) to define with attributes can be assigned from forms instead of attr_accessible option

Related

Rails 3 - how to assign the value to nested attributes before calling save in update action

Models associations are
document.rb
has_many :sections
accepts_nested_attributes_for :sections, :allow_destroy => :true, :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
section.rb
belongs_to :document
has_many :paragraphs, :dependent => :destroy
has_many :contents :through => :paragraphs
validates :user_id, :presence => { :message => "Must be filled" }
paragraph.rb
attr_accessible :user_id, :section_id, :content_id
belongs_to :section
belongs_to :content
validates :user_id, :section, :content, :presence => { :message => "Must be filled" }
paragraphs table just like a intermediate table for sections and contents and I want to save records in documents, sections and paragraphs table using single submission.
So I designed form as like
_form.html.erb
<%= form_for #document, :validate => true do |f| %>
<%= f.error_messages %>
<%= f.text_field :name %>
<% f.fields_for :sections do |builder| %>
<%= builder.text_field :name %>
<%= builder.select :content_ids .... {:multiple => true} %>
<% end %>
<% end %>
example parameters when submiting the form
{"document"=>{"name"=>"sdf", "sections_attributes"=>{"0"=>{"name"=>"sdf", "description"=>"sdf", "_destroy"=>"0", "content_ids" => ["1", "2"]}}, "commit"=>"Update Document", "id"=>"3"}
In additionally, I am updating current_user's id to user_id column of paragraphs table.
update
#document = Document.find(params[:id])
#document.attributes = params[:document]
#document.sections.each {|section|
section.user_id = current_user.id
section.paragraphs.each {|paragraph| paragraph.user_id = current_user.id}
}
if #document.save!
# success
else
render :action => 'edit'
end
I got "Validation failed: User Must be filled".
Is validation triggered when assigning attributes using object.attributes= as above
How to assign the value to user_id in paragraph object before calling save method
Might help.
<%= f.hidden_field :user_id, value: current_user.id %>

Access attribute from association

I have a Customer and Invoice Model. A customer has many invoices and an invoice belongs_to a customer.
class Customer < ActiveRecord::Base
attr_accessible :billing_address, :customer_currency, :email, :first_name, :last_name, :mobile, :name, :payment_terms, :phase_type, :pays_vat
validates_presence_of :first_name, :last_name, :mobile, :billing_address, :payment_terms, :phase_type, :customer_currency
has_many :invoices
validates :email,
:presence => true,
:uniqueness => true,
:email_format => true
validates :name, :mobile, :presence => true, :uniqueness => true
end
Invoice Model is
class Invoice < ActiveRecord::Base
belongs_to :customer
attr_accessible :approved_by, :due_date, :invoice_date, :terms, :customer_id, :customer
validates :invoice_date, presence: true
validates :due_date, presence: true
validates :customer, presence: true
I am trying to create an index page that lists all the invoices in the system and this will invoice showing a customer Name to whom the invoice belongs. How can i retrieve that and clearly depict it in my model and view?
I think you've already created customer and invoice controllers and views (if not do it by generate scaffold). Then list invoices in views\invoices\index.html.erb:
<table>
<tr>
<th>Invoice</th>
<th>Customer/th>
</tr>
<% #invoices.each do |invoice| %>
<tr>
<td><%= invoice.num %></td>
<td><%= invoice.customer.first_name %></td>
</tr>
<% end %>
</table>
Of course, you should declare #invoices in controllers/invoices_controller.rb
def index
#invoices = Invoice.includes(:customer).all
end

Rails 3 UnknownAttributeError For Nested Model

I've been getting the UnkownAttributeError for no particular reason, my models seem to be setup correctly...
School.rb
class School < ActiveRecord::Base
attr_protected :id, :created_at, :updated_at
#relationships
has_many :users
accepts_nested_attributes_for :users
end
My School model used to have the following, but it produced a MassAssignmentSecurity error for the user fields:
attr_accessible :country, :name, :state_or_province, :users_attributes
User.rb
class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation, :remember_me, :username, :instructor_id, :first_name, :last_name, :school_id
#relationships
belongs_to :school
end
new.html.haml
= simple_form_for #school do |f|
.well
= f.input :name, :as => :hidden
= f.input :country, :as => :hidden
= f.input :state_or_province, :as => :hidden
.well
= f.simple_fields_for #school.users.build do |user_form|
= user_form.input :first_name, :required => true
= user_form.input :last_name, :required => true
= user_form.input :username, :required => true
...
= f.button :submit, "Next"
Note: #school is being populated in my new action from session information gathered on the previous page, I'm making a multi-step form. The school data is perfectly valid, if I was to remove the user form it would have no trouble saving the school.
The specific error message I'm getting in my create action:
ActiveRecord::UnknownAttributeError in SchoolsController#create
unknown attribute: user
And the sent params looks a little like this:
{"school"=>{"name"=>"Elmwood Elementary", "country"=>"38",
"state_or_province"=>"448", "user"=>{"first_name"=>"joe",
"last_name"=>"asdas", "username"=>"asasdads",
"email"=>"asdasd#sdas.ca", "password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]"}}, "commit"=>"Next"}
Is this maybe a bug with either Devise or simple_form? I'm using Rails 3.2.3
Ok, so apparently I needed to provide the symbol :users - the name of the relationship as my first argument for it to work.

"undefined method `companies_path'" error

when I visit 'company/new', then I get the following error:
undefined method `companies_path'
Extracted source (around line #1):
1: <%= form_for(#company) do |f| %>
But when I visit 'company/1/edit' (which uses the same form) everything works fine.
This is the company controller for 'new' and 'edit':
def new
#company = Company.new
end
def edit
#company = Company.find(params[:id])
end
And this is (part of) the form:
<%= form_for(#company) do |f| %>
<!-- Show errors -->
<%= render('layouts/form_errors', :object => #company) %>
I really don't understand the error message, because 'companies_path' is not being used in the code?
Update: here is the routes.rb:
get "users_dashboard/show"
get "login" => "sessions#new", :as => "login"
get "logout" => "sessions#destroy", :as => "logout"
resources :company
resources :relations
resources :activities
resources :contacts
resources :notes
resources :tasks
resources :users
resources :sessions
get "site/index"
get "site/features"
get "site/dashboard"
root :to => 'users_dashboard#show'
And here is the company model:
class Company < ActiveRecord::Base
has_many :users
has_many :relations
has_many :contacts, :through => :relations
has_many :notes, :through => :contacts
has_many :tasks, :through => :contacts
has_one :subscription
accepts_nested_attributes_for :subscription
attr_accessible :name, :address1, :address2, :zipcode, :city, :country, :email, :website, :telephone, :twitter, :linkedin, :code
validates :name, :address1, :zipcode, :city, :country, :code, presence: true
validates_length_of :code, :maximum => 3
end
You should change
resources :company
to
resources :companies

How do I correct this model association?

I've created an album model and a photo model and added it to an existing rails application. I've made the photos model belong to the album model and the album model belong to an existing profile model that belongs to a user model. I don't know if I've associated them wrong and why I'm getting an error.
It's worth noting that when I go to URL/albums then everything works as it should but when I go to URL/profiles/1 (the code below is pasted in the show.html.erb file in the views/profile/ folder) then I get the error below.
This is a simple problem that I just can't solve. The four model files are below:
Album.rb:
class Album < ActiveRecord::Base
belongs_to :profile
has_many :photos, :dependent => :destroy
accepts_nested_attributes_for :photos, :allow_destroy => true
end
Profile.rb:
class Profile < ActiveRecord::Base
belongs_to :user
has_many :albums
def self.get_location(profile)
location = []
location << profile.city unless profile.city.blank?
location << profile.state unless profile.state.blank?
location << profile.country unless profile.country.blank?
location << profile.postal_code unless profile.postal_code.blank?
location
end
def self.missing_fields(profile)
missing = []
if profile.first_name.blank?
missing << "first name"
end
if profile.last_name.blank?
missing << "last name"
end
if profile.job_title.blank?
missing << "job title"
end
missing
end
end
Photo.rb:
require 'paperclip'
class Photo < ActiveRecord::Base
belongs_to :album
has_attached_file :upload,
:url => "/images/:id/:style/:basename.:extension",
:path => ":rails_root/public/images/:id/:style/:basename.:extension",
:styles => {
:thumb => "75x75>",
:small => "200x200>"
}
#add in any validations you may want
end
User.rb:
class User < ActiveRecord::Base
include Gravtastic
gravtastic :size => 120
# associations
has_many :albums
has_many :photos, :through => :albums
has_many :authorizations, :dependent => :destroy
has_one :profile, :dependent => :destroy
has_many :resumes, :dependent => :destroy, :order => 'created_at DESC'
has_many :thoughts, :dependent => :destroy, :order => 'created_at DESC'
has_many :user_threads, :dependent => :destroy, :order => 'created_at ASC'
accepts_nested_attributes_for :profile
# virtual attributes
attr_accessor :first_name, :last_name
# validations
validates_presence_of :first_name
validates_presence_of :last_name
validates_length_of :username, :minimum => 4, :message => " is too short"
validates :email, :email => {:message => " is not valid"}
validates_uniqueness_of :email, :case_sensitive => false
validates_uniqueness_of :username, :case_sensitive => false
validates_length_of :password, :minimum => 4, :message => " is too short"
# authlogic
acts_as_authentic do |config|
config.crypto_provider = Authlogic::CryptoProviders::MD5
config.maintain_sessions = false
config.validate_email_field = false
config.validate_login_field = false
config.validate_password_field = false
config.login_field = :email
config.validate_login_field = false
end
def self.create_from_hash!(hash)
user = User.new(:username => Time.now.to_i, :email => '', :auth_provider => hash['provider'])
user.save(:validate => false)
if hash['provider'].downcase == 'twitter'
user.profile = Profile.create(:first_name => Twitter::Client.new.user(hash['user_info'] ['nickname'].to_s).name)
else
user.profile = Profile.create(:first_name => hash['user_info']['first_name'], :last_name => hash['user_info']['last_name'])
end
user
end
def deliver_password_reset_instructions!
reset_perishable_token!
UserMailer.deliver_password_reset_instructions(self)
end
def activate!
self.active = true
save(false)
end
def deliver_activation_instructions!
reset_perishable_token!
UserMailer.deliver_activation_instructions(self)
end
end
The profile controller has this snippet:
def show
#user = User.find_by_username(params[:id])
#profile = #user.profile
#location = Profile.get_location(#profile)
#resumes = #user.resumes
#albums = #user.albums
#photos = #user.photos
#thoughts = #user.thoughts
#shouts = UserThread.find_profile_shouts(#profile)
#shouters = UserThread.find_shouters(#shouts)
#user_thread = UserThread.new
end
The view has this:
<div id="profile_right_col">
<h2>Albums</h2>
<p>
<b>Name:</b>
<%= #albums %><br />
<% #albums.photos.each do |photo| %>
<h3><%= photo.title %></h3>
<%= image_tag photos.upload.url(:small) %>
<% end %>
</p>
<%= link_to 'Edit', edit_album_path(#albums) %> |
<%= link_to 'Back', albums_path %>
</div>
The Action Controller exception shows:
ActiveRecord::StatementInvalid in Profiles#show
Showing /Users/pawel/Ruby/Apps/cvf/app/views/profiles/show.html.erb where line #137 raised:
SQLite3::SQLException: no such column: albums.user_id: SELECT "albums".* FROM "albums" WHERE ("albums".user_id = 4)
Extracted source (around line #137):
<h2>Albums</h2>
<p>
<b>Name:</b>
<%= #albums %><br />
<% #albums.photos.each do |photo| %>
<h3><%= photo.title %></h3>
You dont have #album variable defined in your show action (you have #albums and the in the views you need to go through #albums array). So its value is nil and it doesn`t have method photos.
It worked after I added Paperclip::Railtie.insert to my application.rb.