0

I have created an app in Rails 4.2.3 I am trying to seed the database but after I do rake db:migrate I am getting nil values in the field of the database table. The only piece of code I have in my seeds.rb is:

    User.create![{username: "test", password_digest: "test"}]

In my schema.rb I have:

    create_table "users", force: :cascade do |t|
      t.string   "username"
      t.string   "password_digest"
      t.datetime "created_at",      null: false
      t.datetime "updated_at",      null: false
    end

My User model is:

      class User < ActiveRecord::Base
        has_one :profile, dependent: :destroy
        has_many :todo_lists, dependent: :destroy
        has_many :todo_items, through: :todo_lists, source: :todo_items
      end

There are other people that experienced the same problem like here and here but I don't think that the solutions apply to my case as I do not have any attr_accessor in any of my models.

Anyone knows why that might be happening?

Community
  • 1
  • 1
IliasP
  • 91
  • 8

1 Answers1

2

brace-types matter...

use the following instead

User.create!( username: "test", password_digest: "test" )

This tells rails to create a single user, using the hash that contains username "test" and password "test"

what you have is telling rails to create a user with an array [] that contains a hash {}... but create is not expecting an array of hashes - it's expecting just a single hash.

EDIT: re: using []

That's because when you don't use () but do use [], then ruby has to guess what you mean... are you passing an array to a method or are you calling the array-indexing method on a variable? (or hash-indexing if it's not an integer in the brackets)?

If you put the [] right next to the word create! (eg User.create![]) ruby will probably interpret that as the latter... eg it's looking for an variable on the User class called create!... and then tries to look for a key of that hash called {username: "test", password_digest: "test"}, {username: "test2", password_digest: "test2"} and then it gets confused because when you use the array-indexing method [] you should pass it only one key to find, not two ({username: "test", password_digest: "test"} is the first and {username: "test2", password_digest: "test2"} is the second)... thus giving you the error that you're trying ot pass 2 arguments instead of one... but also just using the wrong interpretation to begin with.

neither of which is what you want...

If you leave a space between the [] and create! then ruby is more likely to interpret the [] as a parameter being passed to a method... and then it triggers a different error.

To be unambiguous - always use a space... or use parens () when passing an argument that could be ambiguous in this way.

Taryn East
  • 27,486
  • 9
  • 86
  • 108
  • Thank you Taryn - this is really helpful. Quick question - I got confused because in the course I am following we have an example where we create two users using the following code: User.create! [ {username: "test", password_digest: "test"}, {username: "test2", password_digest: "test2"} ] and it works when there is a gap between the create! and the opening of the array but it gives me an error "wrong number of arguments (2 for 1)" when there is not a gap. Would you know why? – IliasP Sep 28 '16 at 22:59
  • I'll update my answer with this as it's too long to write here ;) – Taryn East Sep 28 '16 at 23:06
  • Cool. it's a bit complex, and requires an understanding of how ruby tries to figure out what you mean when you write your code... – Taryn East Sep 28 '16 at 23:13
  • 1
    that's a great explanation and now I get it 100% - thank you so much for taking the time to teach me :) – IliasP Sep 28 '16 at 23:17