Rails3 seed data nested attribute
What am I doing wrong here? The forms work but keep getting "undefined method `to_i' for :street1:Symbol" when trying to seed data.
EDIT = If I do everything as a singular address (has_one instead of has_many) seed works.
EDIT 2 = See answer below for others...
address.rb
class Address < ActiveRecord::Base
attr_accessible :street1, :street2, :city, :state, :zipcode, :deleted_at, :addressable_type, :addressable_id, :current, :full_address, :address_type
belongs_to :addressable, :polymorphic => true
scope :vendor, where("address_type='Vendor'")
before_save :update_full_address
def update_full_address
unless self.street2.blank?
street = self.street1 + "<br />" + self.street2 + "<br />"
else
street = self.street1 + "<br />"
end
citystatezip = self.city + ", " + self.state + " " + self.zipcode
self.full_address = street + citystatezip
end
end
vendor.rb
class Vendor < ActiveRecord::Base
attr_accessible :name, :contact, :phone, :addresses_attributes
has_many :addresses, :as => :addressable
accepts_nested_attributes_for :addresses, :allow_destroy => true, :reject_if => proc { |obj| obj.blank? }
end
seed data
require 'faker'
Vendor.delete_all
["Company A", "Company B", "Company C", "Company D"].each do |c|
params = {:vendor =>
{
:name => c,
:contact => Faker::Name.name,
:phone => Faker::PhoneNumber.phone_number,
:addresses_attributes => {
:street1 => Faker::Address.street_address,
:city => Faker::Address.city,
:state => Faker::Address.us_state_abbr,
:zipcode => Faker::Address.zip_code,
:address_type => "Vendor"
}
}
}
Vendor.create!(params[:vendor])
end
Note the [] for an array when dealing with ha开发者_开发技巧s_many.
require 'faker'
Vendor.delete_all
["Company A", "Company B", "Company C", "Company D"].each do |c|
params = {:vendor =>
{
:name => c,
:contact => Faker::Name.name,
:phone => Faker::PhoneNumber.phone_number,
:addresses_attributes => [{
:street1 => Faker::Address.street_address,
:city => Faker::Address.city,
:state => Faker::Address.us_state_abbr,
:zipcode => Faker::Address.zip_code,
:address_type => "Vendor"
}]
}
}
Vendor.create!(params[:vendor])
end
accepts_nested_attributes_for :foo
is so that you can create forms which create associated records. When you're building things in code, there's no need to use this. You can create the associated records using the association names instead of "address_attributes". Here's one way of doing it, but Rails does expose a bunch of ways of doing this same thing...
["Company A", "Company B", "Company C", "Company D"].each do |c|
vendor_address = Address.new :street1 => Faker::Address.street_address,
:city => Faker::Address.city,
:state => Faker::Address.us_state_abbr,
:zipcode => Faker::Address.zip_code,
:address_type => "Vendor"
Vendor.create! :name => c,
:contact => Faker::Name.name,
:phone => Faker::PhoneNumber.phone_number,
:addresses => [vendor_address]
end
If you are wanting to try and use the nested attributes way, then you don't need the :vendor => {}
part of the hash, you can go straight into the params, and you need addresses_attributes
to be an array, not a hash.
精彩评论