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.
Related
This question already has an answer here:
Rails model fields not updating to database
(1 answer)
Closed 7 years ago.
User model:
class User < ActiveRecord::Base
attr_accessor :name, :email
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
end
The problem is, in the Rails console, the attributes name, email, password, password_confirmation don't show up.
I suspect the first two are caused due to setting attr_accessor :name, :email and the latter two due to has_secure_password
But, when I call those attributes separately, they show up:
Loading development environment (Rails 4.2.0)
2.2.1 :001 > u = User.new(name: "asd", email: "aedede#aece.com", password: "qweasd", password_confirmation: "qweasd")
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil, password_digest: "$2a$10$a98/zxfH0zaT0Hh.xalVPOxwbJiXAkH17BiRg.sV4hw...">
2.2.1 :002 > u
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil, password_digest: "$2a$10$a98/zxfH0zaT0Hh.xalVPOxwbJiXAkH17BiRg.sV4hw...">
2.2.1 :003 > u.name
=> "asd"
2.2.1 :004 > u.email
=> "aedede#aece.com"
2.2.1 :005 > u.password
=> "qweasd"
2.2.1 :009 > u.save
(0.2ms) begin transaction
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('aedede#aece.com') LIMIT 1
SQL (0.4ms) INSERT INTO "users" ("password_digest", "created_at", "updated_at") VALUES (?, ?, ?) [["password_digest", "$2a$10$a98/zxfH0zaT0Hh.xalVPOxwbJiXAkH17BiRg.sV4hwFXp2jUiTnm"], ["created_at", "2015-06-10 02:42:22.437148"], ["updated_at", "2015-06-10 02:42:22.437148"]]
(130.8ms) commit transaction
=> true
2.2.1 :010 > u
=> #<User id: 3, name: nil, email: nil, created_at: "2015-06-10 02:42:22", updated_at: "2015-06-10 02:42:22", password_digest: "$2a$10$a98/zxfH0zaT0Hh.xalVPOxwbJiXAkH17BiRg.sV4hw...">
2.2.1 :011 > u.name
=> "asd"
I've checked everything thoroughly and can't find what's causing this, any insights to what's actually happening under the hood would be deeply appreciated.
password is not a column in your database users, and neither it should be. It is just an attribute. If you have used has_secure_password, and you have - Rails will automatically take the password you specified, encrypt it, and store a password_digest in the database. There would be not password column in the database.
In Rails 4.2, you don't need to write attr_accessor with your column names in your model. If you have defined them in migration, Rails will automagically create getter/setter and a bunch of other helping methods for you. So, you model User should look like following in Rails 4.2:
class User < ActiveRecord::Base
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
end
How do you restrict strings allowed in a string field to specific words?
Example: I have a model attribute animal:string that I would like to exclusively accept ["dog", "cat", "bird", "fish"]. Every thing else would make the object invalid.
Add an inclusion validation to your model:
validates :animal, inclusion: { in: %w(dog cat bird fish) }
As I said, I'd go with Rails Enum feature.
class ModelName < ActiveRecord::Base
enum animals: %w(dog cat)
# ...
end
There is one gotcha which you might notice since this is called enum: you will need to update your database column to be an integer value. Rails will do implicit mapping between the integer value and the index of the value in the array automatically
If you go with Enum feature, having the single line of code, Rails will generate several helper methods for you:
# Query method
model_name.dog?
model_name.cat?
#..
# Action method
model_name.cat!
model_name.dog!
#..
# List of statuses and their corresponding values in the database.
model_name.animals
Tried and Tested :
[arup#app]$ rails c
Loading development environment (Rails 4.1.1)
[1] pry(main)> Pet.create!(animals: 'cat')
(0.3ms) BEGIN
SQL (0.9ms) INSERT INTO "pets" ("animals", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["animals", 1], ["created_at", "2015-02-19 18:27:28.074640"], ["updated_at", "2015-02-19 18:27:28.074640"]]
(42.2ms) COMMIT
=> #<Pet id: 5, animals: 1, created_at: "2015-02-19 18:27:28", updated_at: "2015-02-19 18:27:28">
[2] pry(main)> Pet.create!(animals: 'cow')
ArgumentError: 'cow' is not a valid animals
from /home/arup/.rvm/gems/ruby-2.1.2#app/gems/activerecord-4.1.1/lib/active_record/enum.rb:103:in 'block (3 levels) in enum'
[3] pry(main)> Pet.animals
=> {"dog"=>0, "cat"=>1}
[5] pry(main)> Pet.first.dog?
Pet Load (0.8ms) SELECT "pets".* FROM "pets" ORDER BY "pets"."id" ASC LIMIT 1
=> false
[6] pry(main)> Pet.first.cat?
Pet Load (0.7ms) SELECT "pets".* FROM "pets" ORDER BY "pets"."id" ASC LIMIT 1
=> true
[7] pry(main)> Pet.first.cow?
Pet Load (0.7ms) SELECT "pets".* FROM "pets" ORDER BY "pets"."id" ASC LIMIT 1
NoMethodError: undefined method 'cow?' for #<Pet:0xbf8455c>
from /home/arup/.rvm/gems/ruby-2.1.2#app/gems/activemodel-4.1.1/lib/active_model/attribute_methods.rb:435:in `method_missing'
[8] pry(main)>
Pet.create!(animals: 'cow') throws error, which confirmed that, Pet model wouldn't accept anything other than the enum values.
you can use select field in your form, and write this in your model:
module Animal
dog = 1
cat = 2
bird = 3
fish = 4
end
and in tour form:
<%= f.select :animal, { "dog" => 1, "cat" => 2, "bird" => 3, "fish" => 4} %>
I'm using CarrierWaveDirect to handle image uploads. I have users uploading files that have filenames which are not url friendly such as:
one arizona center.jpg
When I find the corresponding photo object in the console the path comes up as:
p.image.path
=> "uploads/8da5058e-6037-41d4-b311-094aaabf5469/one arizona center.jpg"
That's all good because I can display the image with the image_url method and get:
.../uploads/84cf32df-40eb-462b-88cb-ecc9452d2727/one%20arizona%20center.jpg
The problem is if the photo object is updated. In my case an admin user has to approve the photo. The object simply has a boolean field for 'approved' which gets toggled. When I run:
p.update_attribute(:approved,true)
The path becomes:
p.image.path
=> "uploads/8da5058e-6037-41d4-b311-094aaabf5469/one%2520arizona%2520center.jpg"
Here is what the actual controller action looks like:
def approve
photo = Photo.find(params[:id])
status = photo.update_attribute :approved, true
respond_to do |wants|
...
end
end
Here is a sample from the server log:
Started POST "/admin/photos/7/approve" for 199.223.122.34 at 2013-10-29 20:46:18 +0000
2013-10-29T20:46:18.589054+00:00 app[web.1]: Processing by Admin::PhotosController#approve as */*
2013-10-29T20:46:18.589054+00:00 app[web.1]: Parameters: {"id"=>"7"}
2013-10-29T20:46:18.598598+00:00 app[web.1]: Photo Load (4.2ms) SELECT "photos".* FROM "photos" WHERE "photos"."id" = $1 LIMIT 1 [["id", "7"]]
2013-10-29T20:46:18.603564+00:00 app[web.1]: (4.6ms) BEGIN
2013-10-29T20:46:18.610299+00:00 app[web.1]: Photo Load (3.8ms) SELECT "photos".* FROM "photos" WHERE "photos"."id" = $1 LIMIT 1 [["id", 7]]
2013-10-29T20:46:18.613560+00:00 app[web.1]: (2.3ms) UPDATE "photos" SET "approved" = 't', "image" = '0289da71-14cd-46c1-a42c-feff92ac0303/Screen%2520Shot%25202013%252010%252029%2520at%25201.44.20%2520PM.png', "updated_at" = '2013-10-29 20:46:18.610428' WHERE "photos"."id" = 7
Notice that in the final SQL statement that the 'image' attribute is updated as well as the 'approved' attribute. The non-safe url is now escaped in the local database leading to broken images on the site when supplying the image_url method to an image tag.
Is there any way to easily force url safe filenames with CarrierWaveDirect?
For further information my uploader is as follows:
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWaveDirect::Uploader
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
include CarrierWave::MimeTypes
process :set_content_type
def extension_white_list
%w(jpg jpeg png)
end
end
And the model with the uploader mounted looks like this:
class Photo < ActiveRecord::Base
has_one :business, foreign_key: "eponic_id", primary_key: "business_id"
attr_accessible :image, :description
mount_uploader :image, ImageUploader
scope :approved, where(approved: true)
scope :pending, where(approved: false)
end
UPDATE:
We couldn't pinpoint the exact cause of the issue. Apparently, CarrierWave or CarrierWaveDirect has a callback that is getting called when I run update_attribute on the uploader's parent model. As a work around I'm simply using 'update_column' to skip rails' callback chain. I've filed an issue on github:
https://github.com/dwilkie/carrierwave_direct/issues/113
I'm guessing that the image url is escaped again and again each time you submit the update form. This just suggests that you need to have the unescaped URL available in the form.
If the user submits a url of 'images/my image name.jpg' they should never see 'images/my%20image%20%name.jpg' when the form refreshes, even though this is how you store it internally. You should decode it for display--just pass it through URI.decode when you are outputting it to your form.
(This is different from having an HTML-unsafe string in your form--this is literally just a question of representing user input exactly as it was originally without URI encoding. A < character, for example, would still become a < entity on your page, but not a %3C escape sequence. Rails should handle the HTML-safety automatically--just be absolutely sure and try some tags in the URL.)
Edit: not wanting to lead you up some XSS garden path, I tried it out...
%input{ type: :text, value: URI.decode("http://%3Cscript%3Ealert(1);%3C/script%3E.jpg") }
It's fine. It appears in the textbox as http://<script>alert(1);</script>.jpg, but in source it is HTML-safe as expected.
Based on your comments I've decided to set up a little app from scratch and see what happens. It's a plain Rails 4 app. I've brought in the carrierwave gem and created a default uploader. (I'll look at carrierwave_direct in a separate step). I create a Photo model as follows:
class Photo < ActiveRecord::Base
attr_accessible :image, :description, :approved
mount_uploader :image, PhotoUploader
end
The PhotoUploader class just looks like this (all defaults from the generator):
class PhotoUploader < CarrierWave::Uploader::Base
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
Before I go near any forms let's try and make a Photo instance from the console, re-read it, update an attribute, and see what happens to our path. I've got a file called picture of neil.jpg sitting in the root directory of the app.
2.0.0-p195 :001 > p = Photo.new
=> #<Photo id: nil, image: nil, description: nil, approved: nil, created_at: nil, updated_at: nil>
2.0.0-p195 :002 > p.image.class
=> PhotoUploader
All good so far. Let's fake a form hash and then give the uploader a file handle to the data, then save.
2.0.0-p195 :012 > p.image = { file_name: 'picture of neil.jpg', content_type: 'image/jpeg', size: File.size('picture of neil.jpg') }
=> {:file_name=>"picture of neil.jpg", :content_type=>"image/jpeg", :size=>53637}
2.0.0-p195 :013 > p.image = File.open 'picture of neil.jpg'
=> #<File:picture of neil.jpg>
2.0.0-p195 :014 > p.save!
(0.2ms) begin transaction
SQL (1.4ms) INSERT INTO "photos" ("created_at", "image", "updated_at") VALUES (?, ?, ?) [["created_at", Tue, 29 Oct 2013 18:03:49 UTC +00:00], ["image", "picture_of_neil.jpg"], ["updated_at", Tue, 29 Oct 2013 18:03:49 UTC +00:00]]
(1.6ms) commit transaction
=> true
Now if I look in public/uploaders/photo/image/1, there I am, in a file called picture_of_neil.jpg. Carrierwave has sanitized the name but never mind. It hasn't converted the spaces to %20 characters or anything like that.
I'm going to tweak the file name sanitizer regex to accept spaces and try it all again:
2.0.0-p195 :015 > CarrierWave::SanitizedFile.sanitize_regexp = /[^a-zA-Z0-9_\.\-\+ ]/
=> /[^a-zA-Z0-9_\.\-\+ ]/
2.0.0-p195 :016 > p = Photo.new
=> #<Photo id: nil, image: nil, description: nil, approved: nil, created_at: nil, updated_at: nil>
2.0.0-p195 :017 > p.image = { file_name: 'picture of neil.jpg', content_type: 'image/jpeg', size: File.size('picture of neil.jpg') }
=> {:file_name=>"picture of neil.jpg", :content_type=>"image/jpeg", :size=>53637}
2.0.0-p195 :018 > p.image = File.open 'picture of neil.jpg'
=> #<File:picture of neil.jpg>
2.0.0-p195 :019 > p.save!
(0.2ms) begin transaction
SQL (0.6ms) INSERT INTO "photos" ("created_at", "image", "updated_at") VALUES (?, ?, ?) [["created_at", Tue, 29 Oct 2013 18:12:09 UTC +00:00], ["image", "picture of neil.jpg"], ["updated_at", Tue, 29 Oct 2013 18:12:09 UTC +00:00]]
(1.3ms) commit transaction
=> true
Cool, it saved the file with spaces in the name, no problem. If I tweak another attribute and save it again, it's fine as expected. Calling update_attributes is also fine.
carrierwave_direct uses :fog so before I do anything else I'll switch over to using fog (in its excellent mock mode) and try everything I've just done again. My new carrierwave initializer looks like this:
Fog.mock!
S3_CREDENTIALS = { provider: 'AWS',
region: 'eu-west-1',
aws_access_key_id: 'MOCKKEYMOCKKEY',
aws_secret_access_key: 'MOCKSECRETMOCKSECRET' }
S3_DIRECTORY = 'mock_bucket'
# If you're using Fog in mock mode, you have to create an in-memory directory.
Fog::Storage.new(S3_CREDENTIALS).directories.create(key: S3_DIRECTORY, public: false) if Fog.mocking?
CarrierWave::SanitizedFile.sanitize_regexp = /[^a-zA-Z0-9_\.\-\+ ]/
CarrierWave.configure do |config|
config.storage = :fog
config.fog_credentials = S3_CREDENTIALS
config.fog_directory = S3_DIRECTORY
end
Now I'll go through the steps to create a Photo instance again and see what happens. I won't repeat the console output because it is identical. Now I can call p.image.url and see what fog gives me back:
2.0.0-p195 :005 > p.image.url
=> "https://s3.amazonaws.com/mock_bucket/uploads/photo/image/5/picture%20of%20neil.jpg"
Ok! This is exactly what we expect. The path saved with the Photo instance does not contain these %20 characters; it contains spaces. The URL, however, has been escaped. This is all good. What happens if I update the description?
2.0.0-p195 :006 > p.update_attributes description: "A picture of me in a hat"
(0.3ms) begin transaction
SQL (0.5ms) UPDATE "photos" SET "description" = ?, "updated_at" = ? WHERE "photos"."id" = 5 [["description", "A picture of me in a hat"], ["updated_at", Tue, 29 Oct 2013 18:29:34 UTC +00:00]]
(2.1ms) commit transaction
=> true
2.0.0-p195 :007 > p.reload
Photo Load (0.4ms) SELECT "photos".* FROM "photos" WHERE "photos"."id" = ? LIMIT 1 [["id", 5]]
=> #<Photo id: 5, image: "picture of neil.jpg", description: "A picture of me in a hat", approved: nil, created_at: "2013-10-29 18:26:57", updated_at: "2013-10-29 18:29:34">
2.0.0-p195 :008 > p.image.url
=> "https://s3.amazonaws.com/mock_bucket/uploads/photo/image/5/picture%20of%20neil.jpg"
Still all good. Now, if somehow the file name was set to the url and not the original file name, you can see how this would repeatedly get escaped and re-escaped. But as you say--you are only updating one field.
Let's bring in carrierwave_direct to see what it does. My PhotoUploader class now looks like this:
class PhotoUploader < CarrierWave::Uploader::Base
include CarrierWaveDirect::Uploader
end
I've gone through the documented steps to the letter to create an upload form.
ARGH, at this point I'm stumped because it doesn't seem to play nice with Fog in mock mode. It directs me to the real s3 servers, so the round trip to update my new model can't happen. Sorry. I'll try the same things later via the console, when I have some more time.
OK, got it working via the console. Hopefully enough to see what's going on. I've had to mute the validations, but look below--I'm reproducing the behaviour you're seeing.
2.0.0-p195 :027 > class CarrierWaveDirect::Validations::ActiveModel::FilenameFormatValidator < ::ActiveModel::EachValidator
2.0.0-p195 :028?> def validate_each(record, attribute, value)
2.0.0-p195 :029?> end
2.0.0-p195 :030?> end
=> nil
2.0.0-p195 :031 > class CarrierWaveDirect::Validations::ActiveModel::RemoteNetUrlFormatValidator < ::ActiveModel::EachValidator
2.0.0-p195 :032?> def validate_each(record, attribute, value)
2.0.0-p195 :033?> end
2.0.0-p195 :034?> end
=> nil
2.0.0-p195 :035 > p = Photo.new
=> #<Photo id: nil, image: nil, description: nil, approved: nil, created_at: nil, updated_at: nil>
2.0.0-p195 :036 > p.image = { file_name: 'picture of neil.jpg', content_type: 'image/jpeg' }
=> {:file_name=>"picture of neil.jpg", :content_type=>"image/jpeg"}
2.0.0-p195 :037 > p.image = File.open 'picture of neil.jpg'
=> #<File:picture of neil.jpg>
2.0.0-p195 :038 > p.save!
(0.1ms) begin transaction
Photo Exists (0.2ms) SELECT 1 AS one FROM "photos" WHERE "photos"."image" = '1383074454-35950-4053/picture%2520of%2520neil.jpg' LIMIT 1
SQL (2.2ms) INSERT INTO "photos" ("created_at", "image", "updated_at") VALUES (?, ?, ?) [["created_at", Tue, 29 Oct 2013 19:20:56 UTC +00:00], ["image", "1383074454-35950-4053/picture%2520of%2520neil.jpg"], ["updated_at", Tue, 29 Oct 2013 19:20:56 UTC +00:00]]
(2.5ms) commit transaction
=> true
2.0.0-p195 :039 > p.image.url
=> "https://s3.amazonaws.com/mock_bucket/uploads/1383074454-35950-4053/picture%252520of%252520neil.jpg"
Obviously this url is wrong--for whatever reason, it has been escaped once too many times. Note that I'm not seeing this happen repeatedly on the update of attributes. What I would add is that the carrierwave_direct documentation says that you have to set image.key when creating that object, e.g.
2.0.0-p195 :048 > p.image.key = "1383074454-35950-4053/picture%20of%20neil.jpg"
=> "1383074454-35950-4053/picture%20of%20neil.jpg"
This works fine and the url is not doubly escaped. Are you doing this in your creation step, or are you using the muiltipart-form approach that standard carrierwave would use?
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.
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?