Missing id after model.save - ruby-on-rails

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?

Related

How to allow delayed function to be delayed in Rails test environment

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.

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

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.

rspec serialized Hash - query empty for records

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.

Why does not querying for a date return anything?

I have a model with a dep_date field, which is a date (not datetime). When querying the model for records with a given date, nothing is returned. Using RoR 3.2 with SQLite
1.9.3-p327 :019 > Flight.find(62)
Flight Load (0.4ms) SELECT "flights".* FROM "flights" WHERE "flights"."id" = ? LIMIT 1 [["id", 62]]
=> #<Flight id: 62, dep_city_id: 3, arr_city_id: 15, dep_date: "2013-03-28", dep_time: nil, price_per_adult: #<BigDecimal:b7e3c94,'-0.0',9(9)>, price_per_child: #<BigDecimal:b7e3c30,'-0.0',9(9)>, free_seats: nil, flight_status: nil, created_at: "2013-03-14 22:15:48", updated_at: "2013-03-14 22:15:48", arr_date: "2013-04-15", arr_time: nil, c_flight_time: 0, c_flight_distance: 0>
1.9.3-p327 :020 > Flight.where(:dep_date => "2013-03-28")
Flight Load (0.5ms) SELECT "flights".* FROM "flights" WHERE "flights"."dep_date" = '2013-03-28'
=> []
My first guess would be that Rails is interrupting "2013-03-28" as a string and not as a date. I would suggest trying this:
Flight.where(:dep_date => "2013-03-28".to_date)
This was caused by SQLite3. Querying on dates works fine with PostgreSQL.

Whenever a User object is created, create Profile object too with devise and omniauth

I followed Ryan Bates #235 Devise and OmniAuth (revised) http://railscasts.com/episodes/235-devise-and-omniauth-revised and was able to make it work.
Now, I would like to add a Profile to the User.
So, I tried this...
def self.from_omniauth(auth)
where(auth.slice(:provider, :uid)).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.username = auth.info.nickname
user.profile = user.build_profile
user.profile.name = auth.info.name
user.profile.save
end
end
At first glance, everything seemed ok. But I noticed that it didn't update the "name" attribute.
1.9.3p125 :019 > Profile.last
Profile Load (0.4ms) SELECT "profiles".* FROM "profiles" ORDER BY "profiles"."id" DESC LIMIT 1
=> #<Profile id: 8, user_id: 3, name: nil, created_at: "2012-08-18 06:00:59", updated_at: "2012-08-18 06:00:59">
So I tried to set a value, this is what happens:
1.9.3p125 :020 > p=Profile.last
Profile Load (0.4ms) SELECT "profiles".* FROM "profiles" ORDER BY "profiles"."id" DESC LIMIT 1
=> #<Profile id: 8, user_id: 3, name: nil, created_at: "2012-08-18 06:00:59", updated_at: "2012-08-18 06:00:59">
1.9.3p125 :021 > p.name = "Adam"
=> "Adam"
1.9.3p125 :022 > p.save
(0.1ms) BEGIN
(0.1ms) COMMIT
=> true
1.9.3p125 :023 > p.name
=> "Adam"
1.9.3p125 :024 > p
=> #<Profile id: 8, user_id: 3, name: nil, created_at: "2012-08-18 06:00:59", updated_at: "2012-08-18 06:00:59">
I was expecting that the name would be updated. What should I have done?
Thanks
Try:
accepts_nested_attributes_for :profile
in your User model
I think I found out what was the problem. "name" is a reserved attribute. I changed it to "owner_name" and now p.owner_name="Adam" works. I didn't know I shouldn't use "name" as an attribute.
Thank you all!

Resources