Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting default integer values in activerecord

So I'm trying to set a the default value of a 'votes' column to 0, but when I create instances of answers in rails c or through unit tests, the votes value is always nil. Any ideas on why this isn't working?

I've changed the migration like so:

class AddVotesToAnswers < ActiveRecord::Migration
  def change
    add_column :answers, :votes, :integer, default: 0
  end
end

Here's the model:

class Answer < ActiveRecord::Base
  attr_accessible :is_correct, :question_id, :title, :sms_answer_code, :votes

  belongs_to :question

  def upvote
    self.votes += 1
  end

end

Test Spec

require 'spec_helper'

describe Answer do
  before do
    @answer = Answer.make!
  end

  it "should have a default vote value of zero" do
    binding.pry
    @answer.votes.should eq(0)
  end

end
like image 615
Keith Johnson Avatar asked Jun 10 '13 02:06

Keith Johnson


People also ask

What is null false in rails migration?

The null: false parameter means this column does not allow NULL values. The default: false tells us this column will default to false whenever a value isn't specified. This is nice because we can guarantee this field will always be either true or false now. It can't be null because the database prevents it.


2 Answers

The default for a DB migration must be set at the time at which you run the migration – adding a default value once a table has been created won't work.

If your DB is already seeded (and you don't want to change the schema), the following hook in ActiveRecord will do the job:

class Answer < ActiveRecord::Base
    attr_accessible :is_correct, :question_id, :title, :sms_answer_code, :votes

    belongs_to :question

    before_save :default_vote_count

    def upvote
        self.votes += 1
    end

    def default_vote_count
        self.votes ||= 0
    end
end

EDIT:

If you want to change the actual default value in the DB, you can create a change migration containing the following:

# in console
rails g migration change_default_for_answer_votes

# in migration file
class ChangeDefaultForAnswerVotes < ActiveRecord::Migration

  def change
    change_column :answers, :votes, :integer, :default => 0
  end

end

Some databases (Postgres, for instance) don't automatically assign newly updated default values to existing column entries, so you'll need to iterate through existing answers to manually update each to the default votes count:

# in console
Answer.update_all(votes: 0)
like image 94
zeantsoi Avatar answered Sep 20 '22 03:09

zeantsoi


You need to say that as: add_column :answers, :votes, :integer, :default => 0

like image 31
MERM Avatar answered Sep 21 '22 03:09

MERM