This question already has answers here:
NoMethodError when I try to acces a field of an object taken from the DB
(4 answers)
Closed 7 years ago.
I've added a hstore attribute to my model:
class ChangePerDayAverageInterestToHstore < ActiveRecord::Migration
def change
add_column :companies, :per_day_average_interest, :hstore
end
end
Now when I generate the item via the console, I am able to query it without issue. Like so:
irb(main):002:0> t = Company.new per_day_average_interest: {1 => 10, 2 => 3}
irb(main):011:0> t.per_day_average_interest
=> {"1"=>"10", "2"=>"3"}
irb(main):013:0> t.per_day_average_interest["1"] => "10"
irb(main):014:0> t.per_day_average_interest["2"]
=> "3"
When I save it, then query it, I get a No Method error:
irb(main):028:0> t.save!
(0.2ms) BEGIN SQL (0.3ms) INSERT INTO "companies" ("created_at", "per_day_average_interest", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["created_at", "2015-06-08 19:24:39.694533"], ["per_day_average_interest", "\"1\"=>\"10\",\"2\"=>\"3\""], ["updated_at", "2015-06-08 19:24:39.694533"]]
(21.4ms) COMMIT
=> true
irb(main):029:0> d = Company.where(:id => 44)
Company Load (0.5ms) SELECT "companies".* FROM "companies" WHERE "companies"."id" = 44
=> #<ActiveRecord::Relation [#<Company id: 44, name: nil, average: nil, created_at: "2015-06-08 19:24:39", updated_at: "2015-06-08 19:24:39", revenue_average: nil, country: nil, job: nil, model_name:
nil, average_daily_interest: nil, per_day_average_interest: {"1"=>"10", "2"=>"3"}>]>
irb(main):030:0> d.per_day_average_interest
NoMethodError: undefined method `per_day_average_interest' for #<Company::ActiveRecord_Relation:0x007fa16d296dd0>
from /home/action/.gem/ruby/2.1.1/gems/activerecord-4.1.0/lib/active_record/relation/delegation.rb:136:in `method_missing'
from /home/action/.gem/ruby/2.1.1/gems/activerecord-4.1.0/lib/active_record/relation/delegation.rb:99:in `method_missing'
from (irb):30
from /home/action/.gem/ruby/2.1.1/gems/railties-4.1.0/lib/rails/commands/console.rb:90:in `start'
from /home/action/.gem/ruby/2.1.1/gems/railties-4.1.0/lib/rails/commands/console.rb:9:in `start'
from /home/action/.gem/ruby/2.1.1/gems/railties-4.1.0/lib/rails/commands/commands_tasks.rb:69:in `console'
from /home/action/.gem/ruby/2.1.1/gems/railties-4.1.0/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
from /home/action/.gem/ruby/2.1.1/gems/railties-4.1.0/lib/rails/commands.rb:17:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'
Am I querying it the wrong way? Is there something I am missing?
Thanks!
The where statement returns the collection of objects and your column belongs to one object so you need to do the following
d = Company.where(:id => 44).first
As you can see d is ActiveRecord::Relation object, which is a wrapper of the all Company objects after filtering using where. The reader method per_day_average_interest is defined on the Company model instance, so you need to call as I have shown below.
d.first.per_day_average_interest
if you want all the values d.pluck(:per_day_average_interest).
Related
I follow the [railstutorial][rails tutorial] try to setup a simple web site.
In this page, after inserting several records to the Users table, I use rails console, trying to find out some records. But all findings fail.
Could anyone help explain why it fails? Thanks very much
2.0.0-p247 :064 > User.all
User Load (0.3ms) SELECT "users".* FROM "users"
=> #<ActiveRecord::Relation [#<User id: 1, name: "Shijie", email: "shijiexu#yahoo.com", created_at: "2016-12-24 22:36:56", updated_at: "2016-12-24 22:36:56">, #<User id: 2, name: "chen jie", email: "chejie#yahoo.com", created_at: "2016-12-24 22:37:36", updated_at: "2016-12-24 22:37:36">, #<User id: 3, name: "Michael Hartl", email: "mmm#example.com", created_at: "2016-12-25 20:56:58", updated_at: "2016-12-25 21:21:38">]>
2.0.0-p247 :065 > User.find(name: "Shijie")
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", nil]]
ActiveRecord::RecordNotFound: Couldn't find User with 'id'={:name=>"Shijie"}
from /home/shijiex/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-4.2.0/lib/active_record/core.rb:154:in `find'
from (irb):65
from /home/shijiex/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.2.0/lib/rails/commands/console.rb:110:in `start'
from /home/shijiex/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.2.0/lib/rails/commands/console.rb:9:in `start'
from /home/shijiex/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:68:in `console'
from /home/shijiex/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
from /home/shijiex/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.2.0/lib/rails/commands.rb:17:in `<top (required)>'
2.0.0-p247 :066 > User.find(email: "mmm#example.com")
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", nil]]
ActiveRecord::RecordNotFound: Couldn't find User with 'id'={:email=>"mmm#example.com"}
from /home/shijiex/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-4.2.0/lib/active_record/core.rb:154:in `find'
from (irb):66
from /home/shijiex/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.2.0/lib/rails/commands/console.rb:110:in `start'
The user.rb is generated.
class User < ActiveRecord::Base
has_many :microposts
end
The rails in my version is Rails 4.2.0, though the rails in the tutorial is for v5+.
The find method will look for the record using the id column. So, in your case, it checks for the record with the id value of email: "mmm#example.com" which obviously doesn't exist.
If you want to find records by a column other than id, use find_by method and pass the column name and value as a hash.
User.find_by(email: "mmm#example.com")
For more, read the documentation of find_by
I have a very basic table called radio_inventories
create_table "radio_inventories", id: false, force: true do |t|
t.integer "radio_id"
t.string "location"
t.string "distributor"
t.string "radio_user"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "radio_inventories", ["radio_id"], name:
"index_radio_inventories_on_radio_id"
Along with a very simple model:
class RadioInventory < ActiveRecord::Base
self.table_name = 'radio_inventories'
end
For some reason when I use the rails console to create new instances of these models and save them, it saves just fine
irb(main):001:0> x = RadioInventory.new
=> #<RadioInventory radio_id: nil, location: nil, distributor: nil, radio_user: nil, created_at: nil, updated_at: nil>
irb(main):002:0> x.radio_id = 123
=> 123
irb(main):003:0> x.save
(0.0ms) begin transaction
SQL (1.0ms) INSERT INTO "radio_inventories" ("created_at", "radio_id", "updated_at") VALUES (?, ?, ?) [["created_at", "2016-10-18 02:31:26.487353"], ["radio_id", 123], ["updated_at", "2016-10-18 02:31:26.487353"]]
(41.0ms) commit transaction
=> true
But when I then try to update the record I get an error. This happens when I use .save, .update, or .update_attributes.
irb(main):004:0> x = RadioInventory.first
RadioInventory Load (0.0ms) SELECT "radio_inventories".* FROM "radio_inventories" LIMIT 1
=> #<RadioInventory radio_id: 8565, location: nil, distributor: nil, radio_user: nil, created_at: "2016-10-18 02:22:59", updated_at: "2016-10-18 02:22:59">
irb(main):005:0> x.location = 'IT'
=> "IT"
irb(main):006:0> x.save
(0.0ms) begin transaction
(0.0ms) rollback transaction
TypeError: nil is not a symbol
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activemodel-4.1.8/lib/active_model/dirty.rb:162:in `attribute_was'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/attribute_methods/primary_key.rb:44:in `id_was'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/persistence.rb:494:in `_update_record'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/locking/optimistic.rb:70:in `_update_record'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/attribute_methods/dirty.rb:83:in `_update_record'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/callbacks.rb:310:in `block in _update_record'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activesupport-4.1.8/lib/active_support/callbacks.rb:82:in `run_callbacks'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/callbacks.rb:310:in `_update_record'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/timestamp.rb:70:in `_update_record'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/persistence.rb:483:in `create_or_update'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/callbacks.rb:302:in `block in create_or_update'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activesupport-4.1.8/lib/active_support/callbacks.rb:82:in `run_callbacks'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/callbacks.rb:302:in `create_or_update'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/persistence.rb:103:in `save'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/validations.rb:51:in `save'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/attribute_methods/dirty.rb:21:in `save'
... 2 levels...
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/connection_adapters/abstract/database_statements.rb:201:in `block in transaction'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/connection_adapters/abstract/database_statements.rb:209:in `within_new_transaction'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/connection_adapters/abstract/database_statements.rb:201:in `transaction'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/transactions.rb:208:in `transaction'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/transactions.rb:326:in `with_transaction_returning_status'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/transactions.rb:268:in `block in save'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/transactions.rb:283:in `rollback_active_record_state!'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4.1.8/lib/active_record/transactions.rb:267:in `save'
from (irb):6
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/railties-4.1.8/lib/rails/commands/console.rb:90:in `start'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/railties-4.1.8/lib/rails/commands/console.rb:9:in `start'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/railties-4.1.8/lib/rails/commands/commands_tasks.rb:69:in `console'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/railties-4.1.8/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
from C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/railties-4.1.8/lib/rails/commands.rb:17:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'irb(main):007:0>
I've also this with models/tables named "RadioStatus/radio_statuses" which also failed. But when I try with the model/table named 'RadioTracker/radio_trackers', everything works fine and as expected.
Any insight on why ActiveRecord behaves this way would be greatly appreciated.
When there is no default primary id for a table, Rails throws this error when we try to update a ActiveRecord object. so you can try putting self.primary_key = 'radio_id' at the beginning of RadioInventory model class.
And I see that in your migration there is id: false so I guess this is the problem.
You should do assign value on update_attributes:
x= RadioInventory.first
x.update_attributes(location: 'IT')
I have a problem I create the following model in ROR
create_table "seat_types", :force => true do |t|
t.string "type"
t.string "description"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
but when I add data to the model in rails console the following error appears
the field type is a string not a foreign key
1.9.3-p547 :014 > SeatType
=> SeatType(id: integer, type: string, description: string, created_at: datetime, updated_at: datetime)
1.9.3-p547 :015 > a=SeatType.new
=> #<SeatType id: nil, type: nil, description: nil, created_at: nil, updated_at: nil>
1.9.3-p547 :016 > a.type="SC"
=> "SC"
1.9.3-p547 :017 > a.description="Servicio semicama"
=> "Servicio semicama"
1.9.3-p547 :018 > a.save
(0.2ms) BEGIN
SQL (0.5ms) INSERT INTO `seat_types` (`created_at`, `description`, `type`, `updated_at`) VALUES ('2014-12-02 16:02:37', 'Servicio semicama', 'SC', '2014-12-02 16:02:37')
(43.7ms) COMMIT
=> true
1.9.3-p547 :019 > a
=> #<SeatType id: 4, type: "SC", description: "Servicio semicama", created_at: "2014-12-02 16:02:37", updated_at: "2014-12-02 16:02:37">
1.9.3-p547 :020 > SeatType.all
SeatType Load (0.5ms) SELECT `seat_types`.* FROM `seat_types`
ActiveRecord::SubclassNotFound: The single-table inheritance mechanism failed to locate the subclass: 'A'. This error is raised because the column 'type' is reserved for storing the class in case of inheritance. Please rename this column if you didn't intend it to be used for storing the inheritance class or overwrite SeatType.inheritance_column to use another column for that information.
from /home/fernando/.rvm/gems/ruby-1.9.3-p547#ticket_master/gems/activerecord-3.2.19/lib/active_record/inheritance.rb:143:in `rescue in find_sti_class'
from /home/fernando/.rvm/gems/ruby-1.9.3-p547#ticket_master/gems/activerecord-3.2.19/lib/active_record/inheritance.rb:136:in `find_sti_class'
from /home/fernando/.rvm/gems/ruby-1.9.3-p547#ticket_master/gems/activerecord-3.2.19/lib/active_record/inheritance.rb:62:in `instantiate'
from /home/fernando/.rvm/gems/ruby-1.9.3-p547#ticket_master/gems/activerecord-3.2.19/lib/active_record/querying.rb:38:in `block (2 levels) in find_by_sql'
from /home/fernando/.rvm/gems/ruby-1.9.3-p547#ticket_master/gems/activerecord-3.2.19/lib/active_record/querying.rb:38:in `collect!'
from /home/fernando/.rvm/gems/ruby-1.9.3-p547#ticket_master/gems/activerecord-3.2.19/lib/active_record/querying.rb:38:in `block in find_by_sql'
from /home/fernando/.rvm/gems/ruby-1.9.3-p547#ticket_master/gems/activerecord-3.2.19/lib/active_record/explain.rb:41:in `logging_query_plan'
from /home/fernando/.rvm/gems/ruby-1.9.3-p547#ticket_master/gems/activerecord-3.2.19/lib/active_record/querying.rb:37:in `find_by_sql'
from /home/fernando/.rvm/gems/ruby-1.9.3-p547#ticket_master/gems/activerecord-3.2.19/lib/active_record/relation.rb:171:in `exec_queries'
from /home/fernando/.rvm/gems/ruby-1.9.3-p547#ticket_master/gems/activerecord-3.2.19/lib/active_record/relation.rb:160:in `block in to_a'
from /home/fernando/.rvm/gems/ruby-1.9.3-p547#ticket_master/gems/activerecord-3.2.19/lib/active_record/explain.rb:34:in `logging_query_plan'
from /home/fernando/.rvm/gems/ruby-1.9.3-p547#ticket_master/gems/activerecord-3.2.19/lib/active_record/relation.rb:159:in `to_a'
from /home/fernando/.rvm/gems/ruby-1.9.3-p547#ticket_master/gems/activerecord-3.2.19/lib/active_record/relation/finder_methods.rb:159:in `all'
from /home/fernando/.rvm/gems/ruby-1.9.3-p547#ticket_master/gems/activerecord-3.2.19/lib/active_record/querying.rb:5:in `all'
from (irb):20
from /home/fernando/.rvm/gems/ruby-1.9.3-p547#ticket_master/gems/railties-3.2.19/lib/rails/commands/console.rb:47:in `start'
type is reserved name by STI mechanism, as the error says, so you can't name your column this way, unless you want to use STI. Name it kind, for example.
Reference:
http://guides.rubyonrails.org/active_record_basics.html#schema-conventions
I am try on to insert a value via the Rails console into the database, but it's not working.
the first command is
u=users.create(:name=>"bob",:address=>"Dublin")
this is the output after I running the first command
u=Users.create(:name=>"Ben",:address=>"Dublin")
(0.2ms) BEGIN
SQL (0.3ms) INSERT INTO `users` (`address`, `created_at`, `email`, `name`, `password`, `updated_at`) VALUES ('Dublin', '2012-04-16 23:15:48', NULL, 'Ben', NULL, '2012-04-16 23:15:48')
(9.1ms) COMMIT
=> #<Users id: 2, name: "Ben", password: nil, email: nil, address: "Dublin", created_at: "2012-04-16 23:15:48", updated_at: "2012-04-16 23:15:48">
this is the second command
t=tweets.create(:status=>"I am a tweet from bob",:user=>u)
NameError: undefined local variable or method `tweets' for main:Object
from (irb):4
from /opt/bitnami/ruby/lib/ruby/gems/1.9.1/gems/railties-3.2.1/lib/rails/commands/console.rb:47:in `start'
from /opt/bitnami/ruby/lib/ruby/gems/1.9.1/gems/railties-3.2.1/lib/rails/commands/console.rb:8:in `start'
from /opt/bitnami/ruby/lib/ruby/gems/1.9.1/gems/railties-3.2.1/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
Assuming you have a Tweet model, you want
u = User.first
t = Tweet.create(:status => "I am a tweet from bob", :user => u)
I have a User object and getting name like this is fine:
>u=User.find(1)
>u.name
>jt
but it has an association with an object that when I get the user back it returns the name of the class:
oc=ObjectConnection.find(1)
oc.user.name
> User
and the id is giving me an error:
ruby-1.9.2-p290 :063 > oc.user.id
NoMethodError: User Load (0.4ms) SELECT id, name FROM `users` WHERE (id=1)
undefined method `id' for [#<User id: 1, name: "jt">]:ActiveRecord::Relation
from /Users/jt/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.1.0/lib/active_record/relation.rb:459:in `method_missing'
from (irb):63
from /Users/jt/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.0/lib/rails/commands/console.rb:45:in `start'
from /Users/jt/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.0/lib/rails/commands/console.rb:8:in `start'
from /Users/jt/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.0/lib/rails/commands.rb:40:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
ruby-1.9.2-p290 :064 >
The classes are:
class ObjectConnection < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_many :object_connections
end
What is going on? This seems really simple.
thx
I have a nearly identical relationship between Contact and Company (Contact belongs_to company, company has_many contacts.) Here's my rails console (Rails 3.2, Ruby 1.9.3).
1.9.3p125 :019 > company = Company.find(1)
Company Load (2.7ms) SELECT "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT 1 [["id", 1]]
=> #<Company id: 1, name: "Acme Corp", created_at: "2012-03-20 17:49:44", updated_at: "2012-03-20 17:49:44">
1.9.3p125 :020 > contact = Contact.find(1)
Contact Load (1.8ms) SELECT "contacts".* FROM "contacts" WHERE "contacts"."id" = $1 LIMIT 1 [["id", 1]]
=> #<Contact id: 1, first: "Tom", last: "Harrison", email: "foo#example.com", created_at: "2012-03-12 19:11:57", updated_at: "2012-03-20 17:56:37", birthdate: "1962-02-26", company_id: 1>
1.9.3p125 :021 > contact.company.name
Company Load (0.7ms) SELECT "companies".* FROM "companies" WHERE "companies"."id" = 1 LIMIT 1
=> "Acme Corp"
Perhaps there's some case where "name" was used in an earlier version of AREL? Also, notice the odd SQL syntax ... WHERE (id=1) ... What happens if you look for a different attribute of ObjectConnection?
This is an identical situation, isn't it? Perhaps the version of Rails? Ruby? Seems implausible, but the answer is "You're doing it right".