ruby on rails - ActiveModel::MissingAttributeError (can't write unknown attribute 'Russian Federation'): -


getting strange error when running reduce on activemodel relation. seems calling "c.name" in reduce code causes error. c.name returns string "russian federation". using reduce incorrectly?

here error:

[2014-03-17t21:12:40.174655 #9240] fatal -- : activemodel::missingattributeerror (can't write unknown attribute `russian federation'): app/controllers/registrations_controller.rb:96:in `block in pluck_countries' app/controllers/registrations_controller.rb:96:in `pluck_countries' 

larger stacktrace console:

@third_party_countries.reduce(@hsh) {|hsh, c| hsh[c.name] = thirdpartyshipping.first } activemodel::missingattributeerror: can't write unknown attribute `russian federation' /var/www/html/babiators.com/landf/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.2/lib/active_record/attribute_methods/write.rb:47:in `write_attribute' /var/www/html/babiators.com/landf/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.2/lib/active_record/attribute_methods/dirty.rb:70:in `write_attribute' /var/www/html/babiators.com/landf/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.2/lib/active_record/attribute_methods.rb:341:in `[]=' (irb):3:in `block in irb_binding' /var/www/html/babiators.com/landf/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.2/lib/active_record/relation/delegation.rb:63:in `each' /var/www/html/babiators.com/landf/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.2/lib/active_record/relation/delegation.rb:63:in `reduce' /var/www/html/babiators.com/landf/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.2/lib/active_record/relation/delegation.rb:63:in `method_missing' (irb):3 /var/www/html/babiators.com/landf/vendor/bundle/ruby/2.0.0/gems/railties-4.0.2/lib/rails/commands/console.rb:90:in `start' /var/www/html/babiators.com/landf/vendor/bundle/ruby/2.0.0/gems/railties-4.0.2/lib/rails/commands/console.rb:9:in `start' /var/www/html/babiators.com/landf/vendor/bundle/ruby/2.0.0/gems/railties-4.0.2/lib/rails/commands.rb:62:in `<top (required)>' bin/rails:4:in `require' bin/rails:4:in `<main>' 

here code:

@third_party_countries = country.third_party_countries  @hsh = hashwithindifferentaccess.new @third_party_countries.reduce(@hsh) {|hsh, c| hsh[c.name] = c.third_party_shipping } 

country schema:

create_table "countries", force: true |t|   t.string   "name"   t.float    "shipping_rate"   t.integer  "third_party_shipping_id"   t.datetime "created_at"   t.datetime "updated_at"   t.integer  "product_id" end 

country model:

class country < activerecord::base   belongs_to :third_party_shipping   has_and_belongs_to_many :products   has_many :addresses    validates_presence_of :name   validates_uniqueness_of :name    before_create :init   after_initialize :init    scope :shippable, -> { where(third_party_shipping_id: nil) }   scope :third_party_countries, -> { where.not(third_party_shipping_id: nil) }    def shipping_price      self.shipping_rate * 100   end    def free_shipping     self.shipping_rate <= 0 , self.third_party_shipping_id.nil?   end    def paid_shipping     !self.free_shipping   end    def shipping_display     if self.free_shipping       "free"     elsif self.paid_shipping       self.shipping_rate           end    end    private   def init     if self.shipping_rate.blank?        self.shipping_rate = 0     end   end end 

since you're declaring @hsh outside loop, have no need of complexity introduced inject/reduce. use each:

@hsh = hashwithindifferentaccess.new @third_party_countries.each{ |c| @hsh[c.name] = c.third_party_shipping } 

the problem existing code that, inject/reduce, return value of block passed first argument next invocation. need return hsh block, otherwise value of c.third_party_shipping passed hsh next invocation, , you're doing c.third_party_shipping[c.name].

you could make work returning hsh...

@third_party_countries.reduce(@hsh) |hsh, c|    hsh[c.name] = c.third_party_shipping    hsh end 

but shouldn't. don't need functionality. each_with_object correct method use:

@hsh = @third_party_countries.each_with_object(hashwithindifferentaccess.new) |hsh, c|    hsh[c.name] = c.third_party_shipping end 

you map collection array, , initialize hash array:

@hsh = hashwithindifferentaccess[@third_party_countries.map { |c| [c.name, c.third_party_shipping] }] 

this relies on ability freely convert between arrays , hashes. array [[a, b], [c, d]] converts hash { => b, c => d }.


Comments

Popular posts from this blog

basic authentication with http post params android -

vb.net - Virtual Keyboard commands -

How to get multiresult with multicondition in Sql Server -