Search code examples
ruby-on-railsrubysqlitemigrateseeding

Rails db:seed how to bypass validations


Error Message:

rails aborted!
ActiveRecord::RecordInvalid: Validation failed: Status : Event is Locked

I stored a bunch of test data in seeds.rb that I am having trouble seeding w/ db:seed.

Prediction structure

  {user_id: 2, event_id: 3, fighter_guess: "Jessica Andrade", method_guess: "Decision"},
  {user_id: 2, event_id: 3, fighter_guess: "Claudio Puelles", method_guess: "Submission"},
  {user_id: 2, event_id: 2, fighter_guess: "Vicente Luque", method_guess: "Decision"},
  {user_id: 2, event_id: 2, fighter_guess: "Caio Borralho", method_guess: "TKO/KO"},
  {user_id: 2, event_id: 1, fighter_guess: "Korean Zombie", method_guess: "TKO/KO"},
  {user_id: 2, event_id: 1, fighter_guess: "Petr Yan", method_guess: "Decision"},
  {user_id: 2, event_id: 4, fighter_guess: "Rob Font", method_guess: "Submission"},
  {user_id: 2, event_id: 5, fighter_guess: "Charles Oliveira", method_guess: "Decision"},
  {user_id: 2, event_id: 5, fighter_guess: "Rose Namajunas", method_guess: "Submission"},
  {user_id: 2, event_id: 6, fighter_guess: "Aleksandar Rakic", method_guess: "Decision"},
  ...

I have a validation for the Prediction model that checks for the status of the event_id in question to be "Upcoming", before allowing the prediction to be made. So when I run db:seed, it fails the validation because some of the events are not "Upcoming".

Event structure

  {event_name: "UFC FN: LEMOS x ANDRADE", f1: "Amanda Lemos", f2: "Jessica Andrade", f3: "Clay Guida", f4: "Claudio Puelles", status: "Concluded", date: "Sat, Apr 23"},
  {event_name: "UFC FN: FONT x VERA", f1: "Rob Font", f2: "Marlon Vera", f3: "Andrei Arlovski", f4: "Jake Collier", status: "Concluded", date: "Sat, Apr 30"},
  {event_name: "UFC 274", f1: "Charles Oliveira", f2: "Justin Gaethje", f3: "Rose Namajunas", f4: "Carla Esparza", status: "Upcoming", date: "Sat, May 7"},

Prediction.rb

class Prediction < ApplicationRecord

    belongs_to :event
    belongs_to :user

    validate :prediction_no_longer_allowed



    def prediction_no_longer_allowed
        if self.event.concluded? || self.event.in_progress?
            errors.add(:status, ": Event is Locked")
        end
    end
end

Event.rb

...
    def concluded?
        self.status == "Concluded"
    end

    def in_progress?
        self.status == "In Progress"
    end 

For my scenario of wanting to share the app with others to test functionality, it would save a lot of time if I could bypass validations for seeding purposes.

I am seeding data in order of: User --> Event --> Prediction


Solution

  • You can use insert_all method

    Inserts multiple records into the database in a single SQL INSERT statement. It does not instantiate any models nor does it trigger Active Record callbacks or validations. Though passed values go through Active Record's type casting and serialization.

    Prediction.insert_all([
      {user_id: 2, event_id: 3, fighter_guess: "Jessica Andrade", method_guess: "Decision"},
      {user_id: 2, event_id: 3, fighter_guess: "Claudio Puelles", method_guess: "Submission"},
      {user_id: 2, event_id: 2, fighter_guess: "Vicente Luque", method_guess: "Decision"},
      {user_id: 2, event_id: 2, fighter_guess: "Caio Borralho", method_guess: "TKO/KO"},
      {user_id: 2, event_id: 1, fighter_guess: "Korean Zombie", method_guess: "TKO/KO"},
      {user_id: 2, event_id: 1, fighter_guess: "Petr Yan", method_guess: "Decision"},
      {user_id: 2, event_id: 4, fighter_guess: "Rob Font", method_guess: "Submission"},
      {user_id: 2, event_id: 5, fighter_guess: "Charles Oliveira", method_guess: "Decision"},
      {user_id: 2, event_id: 5, fighter_guess: "Rose Namajunas", method_guess: "Submission"},
      {user_id: 2, event_id: 6, fighter_guess: "Aleksandar Rakic", method_guess: "Decision"},
    ])
    

    May be it's better to create first specific events and users. And then call user_id: my_super_user.id, event_id: my_super_event.id etc.