I'm getting a PG error and I can't figure out how to rewrite this statement is a way that works. When I run it in the rails console, everything seems to be fine. But when I try to process it as a background job, it borks with the following error:
/Users/lorenzsell/DEV/Heartbeat-pods/app/mailers/notifications_mailer.rb:44:in `community_update'
/Users/lorenzsell/DEV/Heartbeat-pods/app/jobs/send_community_digest_job.rb:17:in `block (2 levels) in perform'
/Users/lorenzsell/DEV/Heartbeat-pods/app/jobs/send_community_digest_job.rb:16:in `block in perform'
/Users/lorenzsell/DEV/Heartbeat-pods/app/jobs/send_community_digest_job.rb:8:in `perform'
/Users/lorenzsell/DEV/Heartbeat-pods/app/jobs/schedule_send_community_digest_job.rb:9:in `block in perform'
/Users/lorenzsell/DEV/Heartbeat-pods/app/jobs/schedule_send_community_digest_job.rb:8:in `each'
/Users/lorenzsell/DEV/Heartbeat-pods/app/jobs/schedule_send_community_digest_job.rb:8:in `perform'
/Users/lorenzsell/DEV/Heartbeat-pods/lib/tasks/email_tasks.rake:10:in `block (2 levels) in <top (required)>'
-e:1:in `<main>'
ActiveRecord::StatementInvalid: PG::FeatureNotSupported: ERROR: FOR UPDATE is not allowed with aggregate functions
: SELECT COUNT(*) FROM "activities" WHERE "activities"."receiver_id" = $1 AND "activities"."is_read" = 'f' FOR UPDATE
/Users/lorenzsell/DEV/Heartbeat-pods/app/mailers/notifications_mailer.rb:44:in `community_update'
Here is the code snippet:
community_ids = Activity.where(receiver_type: "community", is_read: false).uniq.pluck(:receiver_id)
According to the documentation, lock causes ActiveRecord to generate a SELECT ... FOR UPDATE. Postgres won't let you perform a count on such queries (though other databases might--this is probably why it works in the console), so you need to call count on your Activity relation before you call lock.
# base query
notifications = Activity.where(receiver_id: options['id'], is_read: false)
# save count
notifications_count = notifications.count
# apply lock
notifications = notifications.lock(true)
Related
I am adding the elasticsearch gem to an existing rails app hosted on Heroku.
Running MyModel.import in production is raising an error
MultiJson::ParseError: unexpected character at line 1, column 1 [parse.c:690]
As my development and test environments are working perfectly, I assume that this is being caused by the data in MyModel, perhaps an encoding issue. But as this table is quite large, I am having trouble tracking down the problem.
Can anyone confirm that this error is likely to be caused by an
issue in the data being imported?
Is there a way to inspect the JSON data representation that MyModel.import invokes?
EDIT
Following suggestions below, I have tried running a few commands to track down the error.
MyModel.all.each(&:as_json)
MyModel.all.each(&:as_indexed_json)
MyModel.all.each { |r| r.__elasticsearch__.as_indexed_json }
MyModel.all.each { |r| MultiJson.load r.to_json }
are all running without errors. However they do not appear to be returning json, but arrays of records. Is this usual?
[#<MyModel id: 1, ......
Running import on a limited number of records is also causing strange results.
# a single record returns no error
MyModel.import query: -> { where(id: 1) }
=> 0
# multiple records return the error
MyModel.import query: -> { where(id: 1..2) }
MultiJson::ParseError: unexpected character at line 1, column 1 [parse.c:690]
The full stack trace is
MultiJson::ParseError: unexpected character at line 1, column 1 [parse.c:690]
from /app/vendor/bundle/ruby/2.4.0/gems/multi_json-1.11.3/lib/multi_json/adapters/oj.rb:15:in `load'
from /app/vendor/bundle/ruby/2.4.0/gems/multi_json-1.11.3/lib/multi_json/adapters/oj.rb:15:in `load'
from /app/vendor/bundle/ruby/2.4.0/gems/multi_json-1.11.3/lib/multi_json/adapter.rb:20:in `load'
from /app/vendor/bundle/ruby/2.4.0/gems/multi_json-1.11.3/lib/multi_json.rb:119:in `load'
from /app/vendor/bundle/ruby/2.4.0/gems/elasticsearch-transport-5.0.4/lib/elasticsearch/transport/transport/serializer/multi_json.rb:24:in `load'
from /app/vendor/bundle/ruby/2.4.0/gems/elasticsearch-transport-5.0.4/lib/elasticsearch/transport/transport/base.rb:322:in `perform_request'
from /app/vendor/bundle/ruby/2.4.0/gems/elasticsearch-transport-5.0.4/lib/elasticsearch/transport/transport/http/faraday.rb:20:in `perform_request'
from /app/vendor/bundle/ruby/2.4.0/gems/elasticsearch-transport-5.0.4/lib/elasticsearch/transport/client.rb:131:in `perform_request'
from /app/vendor/bundle/ruby/2.4.0/gems/elasticsearch-api-5.0.4/lib/elasticsearch/api/actions/bulk.rb:95:in `bulk'
from /app/vendor/bundle/ruby/2.4.0/gems/elasticsearch-model-5.0.1/lib/elasticsearch/model/importing.rb:123:in `block in import'
from /app/vendor/bundle/ruby/2.4.0/gems/elasticsearch-model-5.0.1/lib/elasticsearch/model/adapters/active_record.rb:106:in `block in __find_in_batches'
from /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.0.6/lib/active_record/relation/batches.rb:121:in `block in find_in_batches'
from /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.0.6/lib/active_record/relation/batches.rb:214:in `block in in_batches'
from /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.0.6/lib/active_record/relation/batches.rb:198:in `loop'
from /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.0.6/lib/active_record/relation/batches.rb:198:in `in_batches'
from /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.0.6/lib/active_record/relation/batches.rb:120:in `find_in_batches'
from /app/vendor/bundle/ruby/2.4.0/gems/elasticsearch-model-5.0.1/lib/elasticsearch/model/adapters/active_record.rb:105:in `__find_in_batches'
from /app/vendor/bundle/ruby/2.4.0/gems/elasticsearch-model-5.0.1/lib/elasticsearch/model/importing.rb:122:in `import'
from /app/vendor/bundle/ruby/2.4.0/gems/elasticsearch-model-5.0.1/lib/elasticsearch/model.rb:118:in `import'
from (irb):14
from /app/vendor/bundle/ruby/2.4.0/gems/railties-5.0.6/lib/rails/commands/console.rb:65:in `start'
from /app/vendor/bundle/ruby/2.4.0/gems/railties-5.0.6/lib/rails/commands/console_helper.rb:9:in `start'
from /app/vendor/bundle/ruby/2.4.0/gems/railties-5.0.6/lib/rails/commands/commands_tasks.rb:78:in `console'
from /app/vendor/bundle/ruby/2.4.0/gems/railties-5.0.6/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
from /app/vendor/bundle/ruby/2.4.0/gems/railties-5.0.6/lib/rails/commands.rb:18:in `<top (required)>'
from bin/rails:9:in `require'
from bin/rails:9:in `<main>'
This is proving to be a frustrating issue to debug. I am grateful for any further suggestions or ideas.
I have a rails model that keeps track of other models in an app. (unusual, but necessary for this project).
When I try to assign the attribute model_name I get an error that occurs once, but then doesn't occur again.
AppModel
model_name created_at updated_at
----------------------------------------
User
Question
Post
Answer
In console, I'm getting a strange error:
> model = AppModel.new
> model.model_name = "User" # First time causes the error.
> model.model_name = "User" # Second time it works.
Error:
ActiveRecord::DangerousAttributeError: record_changed? is defined by Active Record
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activerecord-4.1.4/lib/active_record/attribute_methods.rb:104:in `instance_method_already_implemented?'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activemodel-4.1.4/lib/active_model/attribute_methods.rb:288:in `block in define_attribute_method'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activemodel-4.1.4/lib/active_model/attribute_methods.rb:285:in `each'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activemodel-4.1.4/lib/active_model/attribute_methods.rb:285:in `define_attribute_method'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activemodel-4.1.4/lib/active_model/attribute_methods.rb:252:in `block in define_attribute_methods'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activemodel-4.1.4/lib/active_model/attribute_methods.rb:252:in `each'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activemodel-4.1.4/lib/active_model/attribute_methods.rb:252:in `define_attribute_methods'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activerecord-4.1.4/lib/active_record/attribute_methods.rb:75:in `block in define_attribute_methods'
from /Users/donaldpinkus/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/mutex_m.rb:73:in `synchronize'
from /Users/donaldpinkus/.rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/mutex_m.rb:73:in `mu_synchronize'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activerecord-4.1.4/lib/active_record/attribute_methods.rb:72:in `define_attribute_methods'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activerecord-4.1.4/lib/active_record/attribute_methods.rb:196:in `method_missing'
from (irb):3
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/railties-4.1.4/lib/rails/commands/console.rb:90:in `start'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/railties-4.1.4/lib/rails/commands/console.rb:9:in `start'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/railties-4.1.4/lib/rails/commands/commands_tasks.rb:69:in `console'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/railties-4.1.4/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/railties-4.1.4/lib/rails/commands.rb:17:in `<top (required)>'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247:in `require'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247:in `block in require'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232:in `load_dependency'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247:in `require'
from /Users/donaldpinkus/Projects/hooker/bin/rails:8:in `<top (required)>'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:241:in `load'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:241:in `block in load'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232:in `load_dependency'
from /Users/donaldpinkus/.rvm/gems/ruby-2.1.5/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:241:in `load'
from /Users/donaldpinkus/.rvm/rubies/ruby-2.1.5/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /Users/donaldpinkus/.rvm/rubies/ruby-2.1.5/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from -e:1:in `<main>'2.1.5 :004 > e.model_name = "User"
=> "User"
"model_name" isn't a reserved word for models, so what is happening here?
This happens because there is already a method in ActiveRecord models, which is called exactly model_name, that returns (obviously) the name of this model (among other things).
From:
.../ruby-2.1.5/gems/activemodel-4.2.0/lib/active_model/naming.rb
# line 222:
Owner: ActiveModel::Naming
Visibility: public
Signature: model_name()
Number of lines: 12
Returns an ActiveModel::Name object for module. It can be used to
retrieve all kinds of naming-related information (See
ActiveModel::Name for more information).
When ActiveRecord fetches an object from the table, it also creates methods with names corresponding to the column names in the table. What happens is it fetches an object, sees a column model_name on the given object, tries to define a method model_name and suddenly finds out that it already exists.
Here's a thing: avoid needlessly long attribute names. If you're defining a name in a model, it can just be name, it's scoped to "model" class anyway, obviously it's the model's name.
The error reporting code, however, likely contains a bug that needs to be tracked down.
In rails console..
Physician.find(1285849521) results in
ArgumentError: wrong number of arguments (1 for 0)
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta4/lib/active_record/connection_adapters/postgresql/database_statements.rb:160:in `initialize'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta4/lib/active_record/connection_adapters/postgresql/database_statements.rb:160:in `new'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta4/lib/active_record/connection_adapters/postgresql/database_statements.rb:160:in `substitute_at'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta4/lib/active_record/relation/query_methods.rb:989:in `block in create_binds'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta4/lib/active_record/relation/query_methods.rb:987:in `each'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta4/lib/active_record/relation/query_methods.rb:987:in `each_with_index'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta4/lib/active_record/relation/query_methods.rb:987:in `create_binds'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta4/lib/active_record/relation/query_methods.rb:962:in `build_where'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta4/lib/active_record/relation/query_methods.rb:586:in `where!'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta4/lib/active_record/relation/query_methods.rb:576:in `where'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta4/lib/active_record/querying.rb:10:in `where'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta4/lib/active_record/core.rb:150:in `block (2 levels) in find'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta4/lib/active_record/statement_cache.rb:80:in `call'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta4/lib/active_record/statement_cache.rb:80:in `create'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0.beta4/lib/active_record/core.rb:149:in `block in find'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/2.1.0/mutex_m.rb:73:in `synchronize'
... 13 levels...
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0.beta4/lib/active_support/dependencies.rb:246:in `load'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0.beta4/lib/active_support/dependencies.rb:246:in `block in load'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0.beta4/lib/active_support/dependencies.rb:237:in `load_dependency'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-4.2.0.beta4/lib/active_support/dependencies.rb:246:in `load'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.1.3/lib/spring/commands/rails.rb:6:in `call'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.1.3/lib/spring/command_wrapper.rb:38:in `call'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.1.3/lib/spring/application.rb:180:in `block in serve'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.1.3/lib/spring/application.rb:153:in `fork'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.1.3/lib/spring/application.rb:153:in `serve'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.1.3/lib/spring/application.rb:128:in `block in run'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.1.3/lib/spring/application.rb:122:in `loop'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.1.3/lib/spring/application.rb:122:in `run'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/spring-1.1.3/lib/spring/application/boot.rb:18:in `<top (required)>'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from /Users/tim/.rbenv/versions/2.1.5/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
and of course..
Physician.find() results in "ActiveRecord::RecordNotFound: Couldn't find Physician without an ID"
My physician.rb is
class Physician < ActiveRecord::Base
self.table_name = "t_phys"
self.primary_key = "sln"
end
I'm using a legacy postgres db, the table t_phys has a natural key called sln, which is a 10 digit integer. There is a physician in the db with sln 1285849521 (the integer in the find method above), which I know because Physician.all() works properly and that's the first record that is displayed.
What am I doing wrong? How can I get the find method to work properly? I'm just getting started with rails again, probably a newbie mistake somewhere. Appreciate the help!
For more detail, when I got to localhost:3000/physicians/1285849521, the page renders:
ArgumentError in PhysiciansController#show
Wrong number of arguments (1 for 0)
Extracted source (around line #160):
159 def substitute_at(column, index)
160 Arel::Nodes::BindParam.new "$#{index + 1}"
161 end
162
163 def exec_query(sql, name = 'SQL', binds = [])
I can provide the full stack trace if necessary.
Seems like it should work, but I'm wondering if the custom primary key is still messing with find.
Maybe this background will help confirm one way or the other:
http://ruby-journal.com/how-to-override-default-primary-key-id-in-rails/
Thanks to Todd Agulnick's comment above, I updated to Rails 4.2 rc2 and the error went away. I encountered a new error, which I resolved and is outside the scope of this question. Thanks Todd!
I've been tasked with adding seeds to an existing Rails project. I've been given a list of twelve survey names and I'm supposed to create them all, storing their id (position in the list of surveys) and name values, then loop over them and add a placeholder survey_question to each. I know how to do it if I were to create a new migration, redefining survey_question as an attribute of survey, but I'm supposed to work with the existing structure where survey and survey_question are distinct classes. And I've hit a wall.
My thinking was to put all the survey names in an array, thus ordering them automatically when the database is seeded:
surveys = [
"SurveyA",
"SurveyB",
"SurveyC",
"SurveyD",
"SurveyE",
"SurveyF",
"SurveyG",
"SurveyH",
"SurveyI",
"SurveyJ",
"SurveyK",
"SurveyL"
]
Then write an each loop that instantiates the Survey class and stores the given name as the name attribute of the database entry. Within that same loop I define survey_question as a placeholder question (which some of you may recognize), and attempt to append it to the Survey being created with the << operator. This is my first point of failure:
surveys.each do |survey|
survey_question = SurveyQuestion.create(body: "What is the average flight speed velocity of an unladen swallow?")
Survey.create(name: survey) << survey_question
end
Great, I've written a loop. I need to verify that it does what I want it to do. So I go to re-seed the database and run rake db:seed. When I do, however, I get a validation error from a line in the seeds.rb file that came with the project. See here:
rake aborted!
undefined method `<<' for #<Survey:0x007fb01fe1a3d0>
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activemodel-4.0.3/lib/active_model/attribute_methods.rb:439:in `method_missing'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/attribute_methods.rb:155:in `method_missing'
/Users/bwstud/Box Sync/Work/Codefellows/erp/db/seeds.rb:95:in `block in <top (required)>'
/Users/bwstud/Box Sync/Work/Codefellows/erp/db/seeds.rb:93:in `each'
/Users/bwstud/Box Sync/Work/Codefellows/erp/db/seeds.rb:93:in `<top (required)>'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:223:in `load'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:223:in `block in load'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:214:in `load_dependency'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:223:in `load'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/railties-4.0.3/lib/rails/engine.rb:540:in `load_seed'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/tasks/database_tasks.rb:154:in `load_seed'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/railties/databases.rake:181:in `block (2 levels) in <top (required)>'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/railties/databases.rake:140:in `block (2 levels) in <top (required)>'
Tasks: TOP => db:setup => db:seed
Here is the offending line (25) from the seeds:
#create seed region
usa = Region.create!(name: "USA")
So I thought, maybe for some wierd reason this was written when the database was created and cannot be overwritten, so if I clear out the database and start anew, it will populate without complaining. I ran rake db:reset. Wrong. At this point I realized there was an error in the way I'd written my each loop above. The error message told me that << is an undefined method for the survey object it was attached to. Here's that messsage.
rake aborted!
undefined method `<<' for #<Survey:0x007fb01fe1a3d0>
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activemodel-4.0.3/lib/active_model/attribute_methods.rb:439:in `method_missing'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/attribute_methods.rb:155:in `method_missing'
/Users/bwstud/Box Sync/Work/Codefellows/erp/db/seeds.rb:95:in `block in <top (required)>'
/Users/bwstud/Box Sync/Work/Codefellows/erp/db/seeds.rb:93:in `each'
/Users/bwstud/Box Sync/Work/Codefellows/erp/db/seeds.rb:93:in `<top (required)>'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:223:in `load'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:223:in `block in load'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:214:in `load_dependency'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:223:in `load'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/railties-4.0.3/lib/rails/engine.rb:540:in `load_seed'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/tasks/database_tasks.rb:154:in `load_seed'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/railties/databases.rake:181:in `block (2 levels) in <top (required)>'
/Users/bwstud/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.0.3/lib/active_record/railties/databases.rake:140:in `block (2 levels) in <top (required)>'
Tasks: TOP => db:setup => db:seed
As a final point of data I checked out what was actually in the database, just to see what was there. This is the result of SELECT * FROM "regions";:
erp_development=# SELECT * FROM "regions"
erp_development-# ;
id | name | created_at | updated_at | default_email_sig
----+------+----------------------------+----------------------------+-------------------
1 | USA | 2014-08-01 17:13:06.733146 | 2014-08-01 17:13:06.733146 |
(1 row)
So now I'm good and stuck. I've been learning as much as I can but my understanding of Ruby and Ruby on Rails is entry-level at best. If anyone out there in Stack-land can help shed some light on this for me I will forever be in your debt.
Thanks,
Brian
<< is Ruby Array method. Survey.create(name: survey) won't return you array, so this is the reason why it fails.
According to the documentation .create method returns the resulting object instead! http://apidock.com/rails/ActiveRecord/Base/create/class
survey = Survey.create(name: survey)
survey.survey_questions << question
The code above should work!
The << method just modifies the returning value of survey.survey_questions, it does not modify the object itself. You should use modifying methods like = or +=. Anyway, I think this is a cleaner way to do the same:
surveys.map do |survey|
Survey.create! do |s|
s.name = survey
s.survey_questions.build(body: "What is the average flight speed velocity of an unladen swallow?")
end
end
I have two tables one is not associated with my rails application invtypes and items table which is associated with my application.
Table invtypes has 20.000 records that i need to move to items table.
Now my first attempt was to simply do a ActiveRecord query on invtypes to get all entries and then go over each entry and create a new Item by instantiating a new Item model adding attributes and then calling model.save
However this also does validation and few other things that slow down making this a 30min task executed in Rails Console since i will be doing this a few times i can't have it be so slow.
So my second idea was to try this with plain old query no Models however this now gives an error:
←[1m←[35m (27.0ms)←[0m INSERT INTO items (typeID, name, description, volume, price, created_at, updated_at) VALUES (0, '#System', '', 0.0, 0.0, '20
13-03-29 04:06:27 +0100', '2013-03-29 04:06:27 +0100');
ActiveRecord::StatementInvalid: Mysql2::Error: Incorrect datetime value: '2013-03-29 04:06:27 +0100' for column 'created_at' at row 1: INSERT INTO ite
ms (typeID, name, description, volume, price, created_at, updated_at) VALUES (0, '#System', '', 0.0, 0.0, '2013-03-29 04:06:27 +0100', '2013-03-29 04:
06:27 +0100');
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:2
33:in `query'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:2
33:in `block in execute'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:280:in
`block in log'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activesupport-3.2.1/lib/active_support/notifications/instrumenter.rb:20:in `instrume
nt'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:275:in
`log'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:2
33:in `execute'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/connection_adapters/mysql2_adapter.rb:214:in `e
xecute'
from (irb):21:in `block in irb_binding'
from (irb):19:in `each'
from (irb):19
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/railties-3.2.1/lib/rails/commands/console.rb:47:in `start'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/railties-3.2.1/lib/rails/commands/console.rb:8:in `start'
from C:/RailsInstaller/Ruby1.9.3/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'
Due to Time.now
result = ActiveRecord::Base.connection.select_all( "SELECT * FROM invtypes" )
time = Time.now
result.each do |row|
sql = "INSERT INTO items (typeID, name, description, volume, price, created_at, updated_at) VALUES (#{row["typeID"]}, '#{row["typeName"]}', '#{row["description"]}', #{row["volume"]}, #{row["basePrice"]}, '#{time}', '#{time}');"
ActiveRecord::Base.connection.execute(sql)
end
How can i go about this with Ruby/Rails or should I write a app in Java | C to execute this query ?
Only executes 10 rows then throws:
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:2
33:in `query'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:2
33:in `block in execute'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:280:in
`block in log'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activesupport-3.2.1/lib/active_support/notifications/instrumenter.rb:20:in `instrume
nt'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:275:in
`log'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:2
33:in `execute'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/activerecord-3.2.1/lib/active_record/connection_adapters/mysql2_adapter.rb:214:in `e
xecute'
from (irb):7:in `block in irb_binding'
from (irb):4:in `each'
from (irb):4
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/railties-3.2.1/lib/rails/commands/console.rb:47:in `start'
from C:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/railties-3.2.1/lib/rails/commands/console.rb:8:in `start'
from C:/RailsInstaller/Ruby1.9.3/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>'
You could try this:
time = Time.now.to_formatted_s(:db)
SQL queries and inserts within a loop are slow. Try with INSERT..SELECT, that command will insert all the rows that you selected with the second statement. I don't know what DB are you using, but for example, if you are using MySQL you can take a look at the documentation of the statement.