I have a Rails model class with a function to be executed at a later time, which is managed by Delayed::Job. Here is the function (simplified):
def fn_with_dj_delay
puts "puts output here"
do_somethting_else
end
handle_asynchronously :fn_with_dj_delay, :run_at => Proc.new { 24.hours.from_now }, :queue => 'my_queue'
When the function is called in my Rails test environment however, the delaying is being skipped. Is it possible for this to perform the same in both environments?
In rails c test the function fires immediately. Here is a slightly simplified and truncated console log:
2.3.1 :004 > x = MyClass.new
2.3.1 :005 > x.save!
2.3.1 :006 > x.fn_with_dj_delay
puts output here
=> #<Delayed::Backend::ActiveRecord::Job id: nil, priority: 0, attempts: 0 # ...
2.3.1 :007 > Delayed::Job.last
Delayed::Backend::ActiveRecord::Job Load (0.3ms) SELECT `delayed_jobs`.* # ...
=> nil
In rails c the function is automatically delayed as instructed. Again, a slightly simplified and truncated console log:
2.3.1 :004 > x = MyClass.new
2.3.1 :005 > x.save!
2.3.1 :006 > x.fn_with_dj_delay
(0.2ms) BEGIN
SQL (0.4ms) INSERT INTO `delayed_jobs` (`handler`, `run_at`, # ...
(0.5ms) COMMIT
=> true
2.3.1 :007 > Delayed::Job.last
Delayed::Backend::ActiveRecord::Job Load (2.2ms) SELECT `delayed_jobs`.* # ...
=> #<Delayed::Backend::ActiveRecord::Job id: 1, priority: 0, attempts: 0 # ...
The only clue I can see is the returned, uninstantiated Delayed::Backend::ActiveRecord::Job object in the test console when the function finishes. If there is something invalid about the object, I could understand this failure, though I would expect an error to be raised. Regardless, this is not at issue:
2.3.1 :004 > res = p.check_for_similar_web_data
puts output here
=> #<Delayed::Backend::ActiveRecord::Job id: nil, priority: 0, attempts: 0 # ...
2.3.1 :005 > res.valid?
=> true
2.3.1 :006 > res.save!
(0.1ms) BEGIN
SQL (0.4ms) INSERT INTO `delayed_jobs` (`handler`, `run_at` # ...
(0.5ms) COMMIT
=> true
This is so simple, I'm surprised and embarrassed I didn't find it before writing this up. I guess the default is false in the test environment?
2.3.1 :003 > Delayed::Worker.delay_jobs = true
2.3.1 :004 > x = MyClass.new
2.3.1 :005 > x.save!
2.3.1 :006 > x.fn_with_dj_delay
(0.2ms) BEGIN
SQL (0.4ms) INSERT INTO `delayed_jobs` (`handler`, `run_at`, # ...
(0.5ms) COMMIT
=> true
2.3.1 :007 > Delayed::Job.last
Delayed::Backend::ActiveRecord::Job Load (2.2ms) SELECT `delayed_jobs`.* # ...
=> #<Delayed::Backend::ActiveRecord::Job id: 1, priority: 0, attempts: 0 # ..
As seen (in reverse) here.
Related
gem 'daemon-spawn'
gem 'delayed_job_active_record'
I have a class "DoingJob" which has a method "perform".
def perform
loop do
// my code in infinity loop
end
In my controller "Simple", I create a DoingJob instance "job" and call Job.delay.perform. Nothing happens and no error apears on web page.
class SimpleController < ApplicationController
require 'opening_job.rb'
def welcome
job = OpeningJob.new
job.delay.perform
end
end
I also performed an experiment on rails console.
user:~/workspace/blog (master) $ rails c
Loading development environment (Rails 4.2.4)
2.2.1 :001 > require 'job.rb'
=> true
2.2.1 :002 > ob = OpeningJob.new
=> #<OpeningJob:0x000000037ff0f0>
2.2.1 :003 > ob.delay.perform
it appears
(0.2ms) begin transaction
SQL (0.8ms) INSERT INTO "delayed_jobs" ("handler", "run_at", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["handler", "--- !ruby/object:Delayed::PerformableMethod\nobject: !ruby/object:OpeningJob {}\nmethod_name: :perform\nargs: []\n"], ["run_at", "2015-11-26 09:24:27.724717"], ["created_at", "2015-11-26 09:24:27.726736"], ["updated_at", "2015-11-26 09:24:27.726736"]]
(21.0ms) commit transaction
=> #<Delayed::Backend::ActiveRecord::Job id: 3, priority: 0, attempts: 0, handler: "--- !ruby/object:Delayed::PerformableMethod\nobject...", last_error: nil, run_at: "2015-11-26 09:24:27", locked_at: nil, failed_at: nil, locked_by: nil, queue: nil, created_at: "2015-11-26 09:24:27", updated_at: "2015-11-26 09:24:27">
2.2.1 :004 > Delayed::Job.last
Delayed::Backend::ActiveRecord::Job Load (0.4ms) SELECT "delayed_jobs".* FROM "delayed_jobs" ORDER BY "delayed_jobs"."id" DESC LIMIT 1
=> nil
So, the problem is that No jobs are added in the database!
But job can be added when I open rails console --sandbox.
I try to convert Hash to JSON before viewing it on page, but can`t convert type of variable. Example in console (rails c):
2.1.5 :001 > #item = Item.find(2)
Item Load (1.6ms) SELECT "items".* FROM "items" WHERE "items"."id" = $1 LIMIT 1 [["id", 2]]
=> #<Item id: 2, nested_params: {"123"=>"123", "456"=>"456"}>
2.1.5 :003 > #item.nested_params.class
=> Hash
2.1.5 :004 > #item.nested_params = #item.nested_params.to_json
=> "{\"123\":\"123\",\"456\":\"456\"}"
2.1.5 :005 > #item.nested_params.class
=> Hash
2.1.5 :006 > #item.nested_params
=> {}
You can visit below link
http://www.rexfeng.com/blog/2012/12/convert-a-ruby-hash-into-valid-json/
I think you have to write require 'json'
I'm using a json field for storing some additional parameters in one of my models.
It works great except for the fact that it doesn't detect changes I make when accessing the data using square brackets:
2.1.1 :002 > p = Payments.last
=> {...}
2.1.1 :003 > p.params.keys
=> ["receipt_data"]
2.1.1 :004 > p.params['verification_data'] = 'test'
=> "test"
2.1.1 :005 > p.params.keys
=> ["receipt_data", "verification_data"]
2.1.1 :006 > p.params_changed?
=> false
2.1.1 :007 > p.save
(0.2ms) BEGIN
(0.2ms) COMMIT
=> true
2.1.1 :008 > Payment.last.params.keys
Payment Load (0.5ms) SELECT "payments".* FROM "payments" ORDER BY "payments"."id" DESC LIMIT 1
=> ["receipt_data"]
How do I force it to save the changes?
to force, before any update. you can say:
p = Payments.last
p.params_will_change!
p.params['verification_data'] = 'test'
p.save
Btw, ActiveRecord is supposed to handle dirty tracking automatically. so, if you can push an app on github which reproduces this issue, I can try to help.
I have a model called Content, with a column called dependencies, serialized as Hash:
class Content < ActiveRecord::Base
attr_accessible :dependencies
serialize :dependencies, Hash
end
This really killed my nerves for the last few hours. I'll appreciate any help/hint.
Questions:
What should be the default (empty) value in migration?
What should be the default (empty) value in FactoryGirl?
Most important - how to query in order to find empty values?
Thanks in advance!
What should be the default (empty) value in migration?
What should be the default (empty) value in FactoryGirl?
In both cases, the empty hash {}
Most important - how to query in order to find empty values?
Since serialized values are stored using YAML, you need to search as follows:
Content.where('dependencies = ?', {}.to_yaml)
Here's an irb transcription for my test of the above:
MacbookAir1:so1 palfvin$ rails c
Loading development environment (Rails 4.0.0)
2.0.0-p247 :001 > u = User.new(role: {})
=> #<User id: nil, role: {}, role2: nil>
2.0.0-p247 :002 > u.save
(0.3ms) begin transaction
SQL (3.3ms) INSERT INTO "users" ("role", "role2") VALUES (?, ?) [["role", "--- {}\n"], ["role2", nil]]
(1.1ms) commit transaction
=> true
2.0.0-p247 :003 > u.role
=> {}
2.0.0-p247 :004 > {}.to_yaml
=> "--- {}\n"
2.0.0-p247 :005 > u
=> #<User id: 4, role: {}, role2: nil>
2.0.0-p247 :006 > User.where(role: {}.to_yaml)
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."role" = '--- {}
'
=> #<ActiveRecord::Relation [#<User id: 3, role: {}, role2: nil>, #<User id: 4, role: {}, role2: nil>]>
2.0.0-p247 :007 >
(Note: I had created a User instance (#3) prior to posting the first version of this answer, which is why that shows up in my where as well).
And here's my user.rb file:
class User < ActiveRecord::Base
has_many :who_rated_comment_rels, foreign_key: "user_id", dependent: :destroy
serialize :role, Hash
serialize :role2
end
You can ignore the stuff not-relevant to your case (i.e. anything other than role). I hack on this project for various StackOverflow purposes.
After creating a new record an saving i can not get the id of the record.
# /var/www# rails g model Foo name:string
invoke active_record
create db/migrate/20120904030554_create_foos.rb
create app/models/foo.rb
invoke test_unit
create test/unit/foo_test.rb
create test/fixtures/foos.yml
# /var/www# rake db:migrate
== CreateFoos: migrating =====================================================
-- create_table(:foos)
-> 0.3451s
== CreateFoos: migrated (0.3452s) ============================================
# /var/www# rails c
Loading development environment (Rails 3.2.8)
1.9.3p194 :001 > foo = Foo.new(:name => 'bar')
=> #<Foo id: nil, name: "bar", created_at: nil, updated_at: nil>
1.9.3p194 :002 > foo.save
(0.2ms) BEGIN
SQL (0.4ms) INSERT INTO `foos` (`created_at`, `name`, `updated_at`) VALUES ('2012-09-04 03:06:26', 'bar', '2012-09-04 03:06:26')
(103.2ms) COMMIT
=> true
1.9.3p194 :004 > Foo.last
Foo Load (0.5ms) SELECT `foos`.* FROM `foos` ORDER BY `foos`.`id` DESC LIMIT 1
=> #<Foo id: 1, name: "bar", created_at: "2012-09-04 03:06:26", updated_at: "2012-09-04 03:06:26">
1.9.3p194 :003 > foo.inspect
=> "#<Foo id: nil, name: \"bar\", created_at: \"2012-09-04 03:06:26\", updated_at: \"2012-09-04 03:06:26\">"
This only seems to be a problem in my application. I have done the same on a fresh rails new foo application and the id shows up.
How can this happen?