-1

I have following rake task to populate my dev database with dummy data. I get an error that my weight and reps can't be blank in the make_contest block which is weird since these fields are not available in the Contest model.

I think it has to do with my "has_many :contests, through: :submissions" relation? How do I fix this?

Error

ActiveRecord::RecordInvalid: Validation failed: Reps can't be blank, Weight can't be blank
/home/christoph/Documenten/kratos/lib/tasks/populate.rake:62:in `block (2 levels) in make_contests'
/home/christoph/Documenten/kratos/lib/tasks/populate.rake:62:in `block in make_contests'
/home/christoph/Documenten/kratos/lib/tasks/populate.rake:58:in `times'
/home/christoph/Documenten/kratos/lib/tasks/populate.rake:58:in `make_contests'
/home/christoph/Documenten/kratos/lib/tasks/populate.rake:15:in `block (2 levels) in <top (required)>'
Tasks: TOP => db:pcontests

Does anybody knows what could be the reason?

rake task

def make_users
  User.create!(
    firstname:              "Christoph",
    name:                   "Geypen",
    username:               "chris88",
    bio:                    "He is the best!",
    email:                  "test@test.be",
    password:               "testtest",
    password_confirmation:  "testtest"
  )

  15.times do |n|
    firstname = Faker::Name.first_name
    name      = Faker::Name.last_name
    username  = Faker::Internet.user_name
    bio       = Faker::Lorem.sentence
    email     = "example-#{n+1}@railstutorial.org"
    password  = "longpassword"

    User.create!(
      firstname:              firstname,
      name:                   name,
      username:               username,
      bio:                    bio,
      email:                  email,
      password:               password,
      password_confirmation:  password,
      data_source:            "rake_populate"
    )
  end
end

def make_contests
  users = User.all.limit(5)

  10.times do
    name        = Faker::Team.creature
    description = Faker::Lorem.sentence

    users.each { |user| user.contests.create!(
      name:         name,
      description:  description,
      admin_id:     user.id,
      ctype_id:     1,
      data_source:  "rake_populate"
    ) }
  end
end

def make_submissions
  users = User.all.limit(15)
  contests = Contest.where(data_source: "rake_populate")

  contests.each do |contest|

    users.each do |user| 
      contest.submissions.create!(
        reps:         rand(1..20),
        weight:       rand(100..350),
        user_id:      user.id,
        contest_id:   contest.id,
        data_source:  "rake_populate"
      )
    end

  end
end

model validations

contest

class Contest < ActiveRecord::Base
  has_many :submissions
  has_many :users, through: :submissions
  belongs_to :admin, class_name: 'User', foreign_key: 'admin_id'
  belongs_to :ctype

  validates_presence_of :name, :admin_id, :ctype_id

submission

class Submission < ActiveRecord::Base
  belongs_to :user
  belongs_to :contest

  validates_presence_of :user_id, :reps, :weight
  validates_uniqueness_of :tonnage, scope: [:user_id, :contest_id]

  before_validation :calculate_tonnage


 # model helpers
  def calculate_tonnage
    self.tonnage = self.weight * self.reps if weight && reps
  end

user

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
        :recoverable, :rememberable, :trackable, :validatable
  devise :omniauthable, omniauth_providers: [:facebook]

  has_many :submissions
  has_many :contests, through: :submissions

  has_one :contest

My create action in the controller looks as following. I am just trying to recreate this using the rake task.

  def create
    @contest = current_user.contests.new(contest_params)
    @contest.admin_id = current_user.id
    @contest.save
    redirect_to contest_submissions_path(@contest)
  end
Christoph
  • 1,347
  • 2
  • 19
  • 36
  • can you please add the `calculate_tonnage` method – Kh Ammad Nov 06 '15 at 10:12
  • I added it to the submission model. (see above) – Christoph Nov 06 '15 at 10:19
  • I am trying to recreate it and when removing the reps and weight validations from my submission model it seems to work. Now I need those validations within my views but not in the rake task. Any way how I can fix this? – Christoph Nov 06 '15 at 17:40

1 Answers1

1

I fixed it by replacing the create with new and saving afterwards. The following question is WHY does that work and create does not?

def make_contests
  users = User.all.limit(5)

  10.times do
    name        = Faker::Team.creature
    description = Faker::Lorem.sentence

    users.each do |user|
      x = user.contests.new(
      name:         name,
      description:  description,
      admin_id:     user.id,
      ctype_id:     1,
      data_source:  "rake_populate")
      x.save
    end

  end
end

UPDATE

aannnnddd problem solved

So create instantiates the new object, validates it, and then saves it to the database. And new only creates the local object but does not attempt to validate or save it to the DB. https://stackoverflow.com/a/2472416/2785289

Community
  • 1
  • 1
Christoph
  • 1,347
  • 2
  • 19
  • 36