创建 rails 对象时如何绕过验证?

How to bypass validations when creating a rails object?

我有以下 rake 任务用虚拟数据填充我的开发数据库。我得到一个错误,我的体重和代表在 make_contest 块中不能为空,这很奇怪,因为这些字段在竞赛模型中不可用。

我觉得和我的"has_many :contests, through: :submissions"关系有关?我该如何解决这个问题?

错误

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

有人知道可能是什么原因吗?

rake 任务

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

模型验证

比赛

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

投稿

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

用户

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

我在控制器中的创建操作如下所示。我只是想使用 rake 任务重新创建它。

  def create
    @contest = current_user.contests.new(contest_params)
    @contest.admin_id = current_user.id
    @contest.save
    redirect_to contest_submissions_path(@contest)
  end

我通过用新的替换创建并在之后保存来修复它。下面的问题是为什么它有效而 create 无效?

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

更新

aannnnddd 问题已解决

所以create实例化新对象,验证它,然后将它保存到数据库中。 new 只创建本地对象,但不会尝试验证或将其保存到数据库中。