0

I'm following Michael's Ruby on Rails tutorial (Chapter 6.2.2) and when I go to the rails console --sandbox to attempt to create Users the outputs come totally outdated.

I update a user's attribute, I return the user and the console outputs nil for all attributes. However if I output the user.attribute the data is there.

The first save fails because a user must have a name, though I had this problem even before addind validations.

What am I missing here? I followed all the instructions and I'm doing pretty basic stuff. I'm executing the following commands:

$ rails console --sandbox
Loading development environment in sandbox (Rails 4.0.2)
Any modifications you make will be rolled back on exit

2.1.0 :001 > user = User.new(name: "", email: "mhartl@example.com")
 => #<User id: nil, name: nil, email: nil, citizen_number: nil, created_at: nil, updated_at: nil> 
2.1.0 :002 > user.save
   (0.1ms)  SAVEPOINT active_record_1
   (0.2ms)  ROLLBACK TO SAVEPOINT active_record_1
 => false 
2.1.0 :003 > user.valid?
 => false 
2.1.0 :004 > user.name = "Bob"
 => "Bob" 
2.1.0 :005 > user.valid?
 => true 
2.1.0 :006 > user
 => #<User id: nil, name: nil, email: nil, citizen_number: nil, created_at: nil, updated_at: nil> 
2.1.0 :007 > user.save
   (0.2ms)  SAVEPOINT active_record_1
  SQL (6.2ms)  INSERT INTO "users" ("created_at", "updated_at") VALUES (?, ?)  [["created_at", Sat, 08 Feb 2014 19:15:37 UTC +00:00], ["updated_at", Sat, 08 Feb 2014 19:15:37 UTC +00:00]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
 => true 
2.1.0 :008 > user
 => #<User id: 1, name: nil, email: nil, citizen_number: nil, created_at: "2014-02-08 19:15:37", updated_at: "2014-02-08 19:15:37">

My user model:

class User < ActiveRecord::Base

  attr_accessor :name, :email, :citizen_number

  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  VALID_CITIZEN_NUMBER_REGEX = /[1-9]\d{7,}/
  validates :name, presence: true, length: { maximum: 50 }
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }
  validates :citizen_number, presence: true, format: { with: VALID_CITIZEN_NUMBER_REGEX }, uniqueness: true

  before_save { lowercase_email() }

  def lowercase_email() 
    self.email = email.downcase
  end

end
dialex
  • 2,706
  • 8
  • 44
  • 74

4 Answers4

1

DiAlex, do you have the code that produced this? I'd like to try it. Since the issue is actually something that happens before the save but after "initialization", I can't see how reload or the validations matter.

Update: Based on the tests and back and forth with you, I think your problem is related with the misuse of attr_accessor and attr_accessible.

Try removing :citizen_number from the attr_accessor. I tried that and your code started working (passing all your tests) and the console started outputting the correct values too.

dialex
  • 2,706
  • 8
  • 44
  • 74
codenoob
  • 800
  • 10
  • 24
  • I continued the tutorial and ignored this problem, so the most up-to-date source has more validations. Nevertheless you should have a pretty stable version here: https://github.com/dialex/dcid/tree/288ac1608c97117ab766e6d2c4c051b084ea8804 I'm also a n00b so yeah :P – dialex Feb 15 '14 at 14:18
  • 1
    DiAlex - I cloned the modeling-users branch (the others don't have a user model). Indeed, I rec'd the same errors and weirdness, with or without the validations. AND when I save, it it saves, but the data is still weird. See the results here (https://gist.github.com/jmcbri/9021295) – codenoob Feb 15 '14 at 16:01
  • I also created a fresh apps, and created a user model, and it does what you'd expect: (https://gist.github.com/jmcbri/9021337) Now we have to figure out what is different between your app and the default. Doubt I'll be able to do that, but I'll try. – codenoob Feb 15 '14 at 16:04
  • OK, if I removed the attr_accessor in your User model, in your repo, it works. Going to look at it more, but it's probably related to the whole whitelisting, thing, and also, I think you (and I) missed that you probably wanted attr_accessible, not attr_accessor (though maybe not for the password, and I think you may not want any of this, as the security on this stuff is moving into the controller). See (http://stackoverflow.com/questions/12444706/confused-about-attr-accessor-and-attr-accessible-in-rails), and (http://www.sitepoint.com/rails-4-quick-look-strong-parameters/) – codenoob Feb 15 '14 at 16:16
0

Use reload

user.reload should give your up to date user with the correct attributes, as explained in the Documentation, it reloads the attributes of this object from the database, so you can now get the object attributes as expected, if they saved correctly

bjhaid
  • 9,592
  • 2
  • 37
  • 47
  • That gives an error `ActiveRecord::RecordNotFound: Couldn't find User without an ID`, since the User is not saved. The console should (I guess) output the correct data even before saving the user. – dialex Feb 15 '14 at 14:14
  • then you might not be saving the user – bjhaid Feb 15 '14 at 15:43
0

Diogo, something is preventing your user.save. After the first attempt of user.save, try user.errors. This will give you a hash with the errors that prevented your model to save.

Most probably you will find an error in your DB Scheme, as the user.valid? returns true.

0

Have you tried without sandbox mode? Perhaps it is somehow restricting the write.

rails console