y.bregey
y.bregey

Reputation: 1499

Seeding model is not working with validatating user in model

My seeds look like:

seeds.rb

seed_file = File.join(Rails.root, 'db', 'seed.yml')
config = YAML::load_file(seed_file)
Article.create(config["articles"])
User::HABTM_Articles.create(config["articles_users"])

seed.yml

articles:
  - status: 0
    title: First article
    body: Some awesome text

articles_users:
  - article_id: 1
    user_id: 1

I make rake db:drop && rake db:create && rake db:migrate.

Then run rake db:seed --trace and get output:

** Invoke db:seed (first_time)
** Execute db:seed
** Invoke db:abort_if_pending_migrations (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute db:abort_if_pending_migrations

My Article table is empty, but Article::HABTM_Users is seeded.

I discovered that problem is in Article model:

article.rb

class Article < ActiveRecord::Base
  has_and_belongs_to_many :users
  validates :title, presence: true, uniqueness: true
  validates :body, presence: true
  validates :users, presence: true #OK when remove this line
  enum status: [:publ, :priv]
end

When remove validates :users, presence: true seeding works fine. How to make seeding run with that user presence validation?

Upvotes: 0

Views: 75

Answers (1)

Robert Nubel
Robert Nubel

Reputation: 7522

The issue is that, at the time you're creating the Article, it has no Users. I know your seed file lists the Users as the very next thing, but ActiveRecord isn't patient about validations! So what you need to do is create the ArticleUsers at the exact same time you create the Article, which you can do in a few ways:

  • Push the article_users definition up and into your articles definition:

    articles:
      - status: 0
        title: First article
        body: Some awesome text
        user_ids: [ 1 ]
    

    I did some testing, and this should actually work:

    irb(main):006:0> Thing.create(name: "thing1", user_ids: [ 1 ] ).users
      User Load (3.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
      SQL (1.4ms)  INSERT INTO "things" ("name", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["name", "thing1"], ["created_at", "2015-07-25 16:38:47.717614"], ["updated_at", "2015-07-25 16:38:47.717614"]]
      SQL (0.5ms)  INSERT INTO "things_users" ("user_id", "thing_id") VALUES ($1, $2) RETURNING "id"  [["user_id", 1], ["thing_id", 2]]
    => #<ActiveRecord::Associations::CollectionProxy [#<User id: 1, name: "Bob", age: nil, created_at: "2015-07-25 16:37:13", updated_at: "2015-07-25 16:37:13">]>
    
  • Use factories, which allow you to express a way to generate test objects more elegantly, a more robust fixture solution, or just turn your seeds file into a Ruby script that knows how to build the seeds properly.

Upvotes: 0

Related Questions