rails--delayed_job : how do I put my code into background - ruby-on-rails

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.

Related

How to save has_many relation in Ruby on Rails using Devise gem?

User Model
class User < ApplicationRecord
belongs_to :tenant, dependent: :destroy
end
Tenant Model
class Tenant < ApplicationRecord
has_many :users
end
Controller
class Accounts::RegistrationsController < Devise::RegistrationsController
Using build_
def create
#tenant = Tenant.new
#user = #tenant.build_user(params)
#tenant.save
end
Using Model
def create
#tenant = Tenant.new
#user = User.build(params)
#tenant.save
end
SQL:
Foreign key is added.
Working
Able to add User model data separately.
Able to add tenant model data separately.
Not working
Not able to map id from the tenant table to the user table's tenant_id.
I tried many possibilities, but not working. Kindly guide me.
DB Screenshot
**Note:*
I am using Devise Gem.
The problem is that build_ is created for the model belonging to.
For example you can do:
Loading development environment (Rails 5.2.1)
2.4.1 :001 > user = User.new(name:'James Kirk')
=> #<User id: nil, name: "James Kirk", created_at: nil, updated_at: nil, tenant_id: nil>
2.4.1 :002 > user.build_tenant(name:'Enterprise')
=> #<Tenant id: nil, name: "Enterprise", created_at: nil, updated_at: nil>
2.4.1 :003 > user.save
(0.1ms) begin transaction
Tenant Create (0.6ms) INSERT INTO "tenants" ("name", "created_at", "updated_at") VALUES (?, ?, ?) [["name", "Enterprise"], ["created_at", "2018-12-30 15:05:52.531519"], ["updated_at", "2018-12-30 15:05:52.531519"]]
User Create (0.6ms) INSERT INTO "users" ("name", "created_at", "updated_at", "tenant_id") VALUES (?, ?, ?, ?) [["name", "James Kirk"], ["created_at", "2018-12-30 15:05:52.534295"], ["updated_at", "2018-12-30 15:05:52.534295"], ["tenant_id", 2]]
(1.3ms) commit transaction
=> true
The above saves the tenant then passes the id to the user and saves the user.
But you can not:
2.4.1 :004 > tenant = Tenant.new(name:'Hazzard')
=> #<Tenant id: nil, name: "Hazzard", created_at: nil, updated_at: nil>
2.4.1 :005 > tenant.build_user(name:'Uncle Jesse')
NoMethodError: undefined method `build_user' for #<Tenant:0x007ff2bbd9b650>
Option for your workflow:
Save the Tenant instance before, get the id then save the User instance:
2.4.1 :009 > tenant = Tenant.new(name:'Hazzard')
=> #<Tenant id: nil, name: "Hazzard", created_at: nil, updated_at: nil>
2.4.1 :010 > tenant.save
(0.1ms) begin transaction
Tenant Create (0.7ms) INSERT INTO "tenants" ("name", "created_at", "updated_at") VALUES (?, ?, ?) [["name", "Hazzard"], ["created_at", "2018-12-30 15:12:36.122931"], ["updated_at", "2018-12-30 15:12:36.122931"]]
(1.7ms) commit transaction
=> true
2.4.1 :011 > user = User.new(name:'Uncle Jesse', tenant_id: tenant.id)
=> #<User id: nil, name: "Uncle Jesse", created_at: nil, updated_at: nil, tenant_id: 4>
2.4.1 :012 > user.save
(0.1ms) begin transaction
Tenant Load (0.2ms) SELECT "tenants".* FROM "tenants" WHERE "tenants"."id" = ? LIMIT ? [["id", 4], ["LIMIT", 1]]
User Create (0.4ms) INSERT INTO "users" ("name", "created_at", "updated_at", "tenant_id") VALUES (?, ?, ?, ?) [["name", "Uncle Jesse"], ["created_at", "2018-12-30 15:12:52.119957"], ["updated_at", "2018-12-30 15:12:52.119957"], ["tenant_id", 4]]
(0.9ms) commit transaction
=> true
As per the description mentioned in the post, it seems like the reference of tenant is not saving in the users table.
Since tenant is having a has_many relationship with users, thus something like menioned below can make it to work:
def create
#tenant = Tenant.find(params[:id])
#user = #tenant.users.build(params)
#user.save
end
Note: the params will be having the attributes of user model, whereas you will be passing the id of the tenant already saved in the database to reference it in user table.
https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

allow_nil: false does not work from rails console

Newbie here, trying to add some rules to a ruby on rails form, specifically I don't want to allow the creation of an item if this has not a name
class Idea < ActiveRecord::Base
mount_uploader :picture, PictureUploader
belongs_to :project
validates :name, presence: true, allow_nil: false
end
Works smoothly if I create a new item from my app, but not happens the same if I create one item from rails console. How can I avoid the creation of an item without name, no matter if this has been created in the app or in the rails console?
The problem is you have to set allow_blank: false instead of allow_nil: false.
In Ruby an empty string is not nil.
"".nil?
#=> false
"".blank?
#=> true
Update your model like this
class Idea < ActiveRecord::Base
mount_uploader :picture, PictureUploader
belongs_to :project
validates :name, presence: true, allow_blank: false
end
If you want know the differences between nil and blank,see this SO post.
Refer these Guides for allow_blank
Try this from console:-
Idea.create(:name => "Something")
Rails console output:-
1.9.3-p385 :005 > c = CabinNumber.create(:name => "Something")
(0.2ms) begin transaction
SQL (1.1ms) INSERT INTO "cabin_numbers" ("created_at", "name", "status", "updated_at") VALUES (?, ?, ?, ?) [["created_at", Sun, 25 May 2014 00:02:04 IST +05:30], ["name", "Something"], ["status", false], ["updated_at", Sun, 25 May 2014 00:02:04 IST +05:30]]
(139.6ms) commit transaction
=> #<CabinNumber id: 11, name: "Something", status: false, created_at: "2014-05-24 18:32:04", updated_at: "2014-05-24 18:32:04">
OR
idea = Idea.new(:name => "hello")
idea.save
Rails console output:-
1.9.3-p385 :007 > c = CabinNumber.new(:name => "hello")
=> #<CabinNumber id: nil, name: "hello", status: false, created_at: nil, updated_at: nil>
1.9.3-p385 :008 > c.save
(0.1ms) begin transaction
SQL (1.0ms) INSERT INTO "cabin_numbers" ("created_at", "name", "status", "updated_at") VALUES (?, ?, ?, ?) [["created_at", Sun, 25 May 2014 00:02:57 IST +05:30], ["name", "hello"], ["status", false], ["updated_at", Sun, 25 May 2014 00:02:57 IST +05:30]]
(155.0ms) commit transaction
=> true
Cannot create if name field is not provided
1.9.3-p385 :003 > c = CabinNumber.create()
(0.2ms) begin transaction
(0.1ms) rollback transaction
=> #<CabinNumber id: nil, name: nil, status: false, created_at: nil, updated_at: nil>

Rails serialization converts 0 to String

I've got a model that uses the default Rails serialization to serialize an array. Behold:
class Account < ActiveRecord::Base
serialize :number_of_free_jobs
end
number_of_free_jobs is an array of FixNums, but for some reason Rails is converting all the entries that are 0 into strings, but leaving the rest as FixNums, check it:
account = Account.last
account.number_of_free_jobs = [10, 5, 0, 1]
account.save
account.number_of_free_jobs
=> [10, 5, "0", 1]
Converting the 0 to a String means some comparisons are failing. I can just map the array with to_i but I'm curious as to why this is happening. I'm using Rails 3.2.13 and Ruby 1.9.3
This doesn't occur on my machine(Sqlite3, Rails 3.2.13 & Ruby 1.9.3):
Loading development environment (Rails 3.2.13)
irb(main):001:0> Account
=> Account(id: integer, number_of_free_jobs: string, created_at: datetime, updated_at: datetime)
irb(main):002:0> Account.create
(0.1ms) begin transaction
SQL (9.5ms) INSERT INTO "accounts" ("created_at", "number_of_free_jobs", "updated_at") VALUES (?, ?, ?) [["created_at", Mon, 20 May 2013 18:19:26 UTC +00:00], ["number_of_free_jobs", nil], ["updated_at", Mon, 20 May 2013 18:19:26 UTC +00:00]]
(179.1ms) commit transaction
=> #<Account id: 2, number_of_free_jobs: nil, created_at: "2013-05-20 18:19:26", updated_at: "2013-05-20 18:19:26">
irb(main):003:0> account = Account.last
Account Load (0.3ms) SELECT "accounts".* FROM "accounts" ORDER BY "accounts"."id" DESC LIMIT 1
=> #<Account id: 2, number_of_free_jobs: nil, created_at: "2013-05-20 18:19:26", updated_at: "2013-05-20 18:19:26">
irb(main):004:0> account.number_of_free_jobs = [10, 5, 0, 1]
=> [10, 5, 0, 1]
irb(main):005:0> account.save
(0.1ms) begin transaction
(0.4ms) UPDATE "accounts" SET "number_of_free_jobs" = '---
- 10
- 5
- 0
- 1
', "updated_at" = '2013-05-20 18:19:46.430558' WHERE "accounts"."id" = 2
(155.9ms) commit transaction
=> true
irb(main):006:0> account.number_of_free_jobs
=> [10, 5, 0, 1]
Can you provide steps to reproduce this issue? perhaps a sample app on github which has this error/bug/behaviour?
The problem was with the Tolk gem installing safe_yaml as a dependency. Removing Tolk removed the dependency and zeroes are no longer being converted to strings. Bit of a strange one, I'll look into why safe_yaml does this...

Rails Engines - is it possible to add associations to the model in a container model like Forem does

This Question is more than a single question so breaking it up into more managable pieces: Rails Engines - simple possible engine to (1) add a model and (2) add the association in the containing class
I am testing out building a Rails engine and am curious whether I can add an association to a specific model in the hosting / container app.
The hosting app has a user model class (yes, this will never chnage) and my engine is called abc and I have a model in my engine called posts (so Abc::Post and the table is abc_posts). I'd like to add to the User class in the main app this association. As a drop dead simple try, I created in my engine:
#located in the engine at: abc/app/models/user.rb
class User < ActiveRecord::Base
has_many :abc_posts
end
the post file:
#located in the engine at: abc/app/models/abc/post.rb
module Abc
class Post < ActiveRecord::Base
attr_accessible :body, :header, :user_id
belongs_to :user
end
end
Via rails console, I was able to create records in the table (easy part) but the User class doesn't know about the association. Any ideas on how to get this done?
thx in advance
edit 1
I've tried using the decorators gem as used in forem (see comment below) and have this file:
#abc/app/decorators/lib/abc/user_class_decorator.rb
Object.const_get(User).class_eval do
has_many :abc_posts, :class_name => "Abc::Post", :foreign_key => "user_id"
end
I have included the decorators via:
lib/abc.rb
require "decorators"
but his doesn't seem to be working. Not sure if this is right strategy or whether syntax is even correct.
That should do the job - specify the class for the relationship:
class User < ActiveRecord::Base
has_many :posts, :class_name => "Abc::Post"
end
Hmmm, I created an example and it does work ...
class Parent < ActiveRecord::Base
has_many :children, :class_name => "Abc::Child"
end
The module with the class Child is in the model/abc.
module Abc
class Child < ActiveRecord::Base
belongs_to :parent
end
end
Here the journal
1.9.3-p194 :001 > Parent.create(:name => 'Mr Daddy')
(0.1ms) begin transaction
SQL (9.4ms) INSERT INTO "parents" ("created_at", "name", "updated_at") VALUES (?, ?, ?) [["created_at", Fri, 03 May 2013 10:49:54 UTC +00:00], ["name", "Mr Daddy"], ["updated_at", Fri, 03 May 2013 10:49:54 UTC +00:00]]
(1.9ms) commit transaction
=> #<Parent id: 1, name: "Mr Daddy", created_at: "2013-05-03 10:49:54", updated_at: "2013-05-03 10:49:54">
1.9.3-p194 :002 > Abc::Child.create(:name => 'Sammy boy', :parent => Parent.first )
Parent Load (0.3ms) SELECT "parents".* FROM "parents" ORDER BY "parents"."id" ASC LIMIT 1
(0.1ms) begin transaction
SQL (117.3ms) INSERT INTO "children" ("created_at", "name", "parent_id", "updated_at") VALUES (?, ?, ?, ?) [["created_at", Fri, 03 May 2013 10:49:58 UTC +00:00], ["name", "Sammy boy"], ["parent_id", 1], ["updated_at", Fri, 03 May 2013 10:49:58 UTC +00:00]]
(2.1ms) commit transaction
=> #<Abc::Child id: 1, name: "Sammy boy", parent_id: 1, created_at: "2013-05-03 10:49:58", updated_at: "2013-05-03 10:49:58">
1.9.3-p194 :003 > Abc::Child.create(:name => 'Milly girl', :parent => Parent.first )
Parent Load (0.3ms) SELECT "parents".* FROM "parents" ORDER BY "parents"."id" ASC LIMIT 1
(0.2ms) begin transaction
SQL (0.8ms) INSERT INTO "children" ("created_at", "name", "parent_id", "updated_at") VALUES (?, ?, ?, ?) [["created_at", Fri, 03 May 2013 10:50:15 UTC +00:00], ["name", "Milly girl"], ["parent_id", 1], ["updated_at", Fri, 03 May 2013 10:50:15 UTC +00:00]]
(2.7ms) commit transaction
=> #<Abc::Child id: 2, name: "Milly girl", parent_id: 1, created_at: "2013-05-03 10:50:15", updated_at: "2013-05-03 10:50:15">
1.9.3-p194 :004 > Parent.first.children.first
Parent Load (0.4ms) SELECT "parents".* FROM "parents" ORDER BY "parents"."id" ASC LIMIT 1
Abc::Child Load (0.3ms) SELECT "children".* FROM "children" WHERE "children"."parent_id" = ? ORDER BY "children"."id" ASC LIMIT 1 [["parent_id", 1]]
=> #<Abc::Child id: 1, name: "Sammy boy", parent_id: 1, created_at: "2013-05-03 10:49:58", updated_at: "2013-05-03 10:49:58">
1.9.3-p194 :005 > Parent.first.children.last
Parent Load (0.5ms) SELECT "parents".* FROM "parents" ORDER BY "parents"."id" ASC LIMIT 1
Abc::Child Load (0.4ms) SELECT "children".* FROM "children" WHERE "children"."parent_id" = ? ORDER BY "children"."id" DESC LIMIT 1 [["parent_id", 1]]
=> #<Abc::Child id: 2, name: "Milly girl", parent_id: 1, created_at: "2013-05-03 10:50:15", updated_at: "2013-05-03 10:50:15">
1.9.3-p194 :006 > Parent.first.children.count
Parent Load (0.3ms) SELECT "parents".* FROM "parents" ORDER BY "parents"."id" ASC LIMIT 1
(0.3ms) SELECT COUNT(*) FROM "children" WHERE "children"."parent_id" = ? [["parent_id", 1]]
=> 2

Strange ActiveRecord model behavior

I have model
class Owner < ActiveRecord::Base
attr_accessible :telephone
validates_uniqueness_of :telephone
validates_telephone_number_of :telephone
before_validation :telephone_normalize
end
in rails console
a = Owner.new(:telephone => '949123456')
=> #<Owner id: nil, telephone: "949123456", created_at: nil, updated_at: nil>
1.9.3-p362 :002 > a.valid?
Owner Exists (0.1ms) SELECT 1 AS one FROM "owners" WHERE "owners"."telephone" = '+421949123456' LIMIT 1
=> false
1.9.3-p362 :003 > a
=> #<Owner id: nil, telephone: "421949123456", created_at: nil, updated_at: nil>
The same, when I save unique number:
1.9.3-p362 :006 > a.telephone = '949123457'
=> "949123457"
1.9.3-p362 :007 > a.save
(0.1ms) begin transaction
Owner Exists (0.2ms) SELECT 1 AS one FROM "owners" WHERE "owners"."telephone" = '+421949123457' LIMIT 1
SQL (2.3ms) INSERT INTO "owners" ("created_at", "telephone", "updated_at") VALUES (?, ?, ?) [["created_at", Wed, 16 Jan 2013 11:55:44 UTC +00:00], ["telephone", "421949123457"], ["updated_at", Wed, 16 Jan 2013 11:55:44 UTC +00:00]]
(88.3ms) commit transaction
=> true
Rails (3.2.11) omits '+' in the beginning of number. Type of number is string. It also saves it without plus sign (if it is unique), but when validating, it calls with plus sign.
What am I doing wrong?
It think telephone column in database is integer type. So the string you have passed is out of its range. That's why you have face this problem.
Unfortunetaly there was bug in my validates_telephone_number_of validator. It had modified attribute :-/
Say
> a = 'aaa' # => 'aaa'
> b = a.to_s # => 'aaa'
> b << 'c' # => 'aaac'
> b # => 'aaac'
> a # => 'aaac'
It is needed to use b = a.to_s.dup.

Resources