0

Currently when trying to add a new user to my User table via rails console or seed data, everything is nil.

In my seed file I am running:

u1 = User.create(:from_email => "v@gmail.com", :to_email => "s@gmail.com", :from_name=>"Vero", :to_name=>"Spencer", :message=>"Test message", :password=>"chicken", :id => 1)
u1.save!

If I run this via seed data in rails or via rails console and then check the Postgres database with User.all I get:

#<User id: 1, from_name: nil, to_name: nil, from_email: nil, to_email: nil, message: nil, created_at: "2014-12-10 02:34:02", updated_at: "2014-12-10 02:34:02", password: nil>

I've been dealing with this for hours, starting to get quite confused. Help would be appreciated, my model and schema is below:

class User < ActiveRecord::Base
attr_accessor :from_name, :from_email, :to_name, :to_email, :message, :password, :id

before_save { self.from_email = from_email.downcase }
before_save { self.to_email = to_email.downcase }
before_save { self.password = "merrychristmas#{ Random.rand(1000) }" }

validates :id, :presence => true, :uniqueness => true
validates :from_name, :presence => true, :uniqueness => false
validates :to_name, presence: true, :uniqueness => false
validates :from_email, presence: true, format: { with: /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i}
validates :to_email, presence: true, format: { with: /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i }
validates :message, presence: true, length: { maximum: 50 }

def self.authenticate(id, password)
    user = find(id)
if user && user.password
        user
else
        nil
end
end

end

Schema:

ActiveRecord::Schema.define(version: 20141209104326) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "users", force: true do |t|
    t.string   "from_name"
    t.string   "to_name"
    t.string   "from_email"
    t.string   "to_email"
    t.text     "message"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "password"
  end

end

SQL

(0.3ms)  BEGIN
  User Exists (0.5ms)  SELECT  1 AS one FROM "users"  WHERE "users"."id" = 2 LIMIT 1
  SQL (0.4ms)  INSERT INTO "users" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"  [["created_at", "2014-12-10 04:15:33.579478"], ["updated_at", "2014-12-10 04:15:33.579478"]]
   (6.5ms)  COMMIT
=> #<User id: nil, from_name: nil, to_name: nil, from_email: nil, to_email: nil, message: nil, created_at: "2014-12-10 04:15:33", updated_at: "2014-12-10 04:15:33", password: nil>
Swalden
  • 53
  • 1
  • 6
  • What *SQL* is it generating? Also, while in this case the *regex* does appear to match that email address, at least in a pure *Ruby* context, I would not recommend validating the format of an email, since there are so many edge cases, and a valid format isn't the same as a valid email address in any case (or if you must, use a fully RFC-compliant parser as opposed to a regex). – khampson Dec 10 '14 at 03:38
  • 1
    also it seems wrong when you pass all fields to `attr_accessor`, shouldn't it be `attr_accesible` if you are using rails 3? – kasperite Dec 10 '14 at 03:49
  • This is the SQL output (0.3ms) BEGIN User Exists (0.5ms) SELECT 1 AS one FROM "users" WHERE "users"."id" = 2 LIMIT 1 SQL (0.4ms) INSERT INTO "users" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", "2014-12-10 04:15:33.579478"], ["updated_at", "2014-12-10 04:15:33.579478"]] (6.5ms) COMMIT => # – Swalden Dec 10 '14 at 04:15
  • I'm using Rails4, where I think attr_accessor is correct – Swalden Dec 10 '14 at 04:23
  • I believe you can rule out all of the validations being a problem, because `save!` would return an error and the `SQL` would `ROLLBACK` instead of `COMMIT`. – sealocal Dec 10 '14 at 04:52
  • However, it's pretty easy to comment out lines one-by-one until your model saves a record, then ask about a specific line that is causing you trouble. – sealocal Dec 10 '14 at 04:54

3 Answers3

4

Your problem is using attr_accessor in your model. This should only be used where you want to define getter/setter methods for an object which you do not want to store in the database. See here for more information.

Remove the entirety of the line that starts attr_accessor and your code will work.

Also remove the assignment of the id and the line that validates its presence. This is handled automatically by the database.

Community
  • 1
  • 1
Robin Fisher
  • 1,454
  • 1
  • 13
  • 23
0

Have you tried it without the ID? That field is auto incremented by the db. So basically remove all references to :id => 1 and :validates :id....

JC Avena
  • 231
  • 1
  • 5
0

Removing attr_accessor from model .rb files should work.

Aziz Zoaib
  • 661
  • 8
  • 21