未设置默认布尔值Rails 4 Postgres

时间:2014-09-15 22:36:13

标签: ruby-on-rails postgresql ruby-on-rails-4

我使用以下代码创建了向用户表的迁移:

add_column :users, :email_confirmed, :boolean, :default => false

但是,当创建新用户时,:email_confirmed字段会自动设置为true。这发生在任何人身上吗?我错过了一些简单的事吗?任何见解都是受欢迎的。

我的用户模型:

class User < ActiveRecord::Base
    has_many :microposts, dependent: :destroy
  has_many :relationships, foreign_key: "follower_id", dependent: :destroy
  has_many :followed_users, through: :relationships, source: :followed
  has_many :reverse_relationships, foreign_key: "followed_id",
                                   class_name:  "Relationship",
                                   dependent:   :destroy
  has_many :followers, through: :reverse_relationships, source: :follower
    has_secure_password
    before_save { email.downcase! }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(?:\.[a-z\d\-]+)*\.[a-z]+\z/i
    before_create :create_remember_token
  before_create :confirmation_token
  validates :name, presence: true, length: { maximum: 50 }
      validates :email, presence: true, 
        format: { with: VALID_EMAIL_REGEX }, 
              uniqueness: { case_sensitive: false }
      validates :password, length: { minimum: 6 }, :unless => :email_activate

  def feed
     Micropost.from_users_followed_by(self)
  end

  def following?(other_user)
    relationships.find_by(followed_id: other_user.id)
  end

  def follow!(other_user)
    relationships.create!(followed_id: other_user.id)
  end

  def unfollow!(other_user)
    relationships.find_by(followed_id: other_user.id).destroy
  end

  def User.new_remember_token
    SecureRandom.urlsafe_base64
  end

  def User.digest(token)
    Digest::SHA1.hexdigest(token.to_s)
  end

  def email_activate
    self.email_confirmed = true
    save!(:validate => false)
  end

  def send_password_reset
      self.password_reset_token = SecureRandom.urlsafe_base64.to_s
      self.password_reset_sent_at = Time.zone.now
      save!(:validate => false)
      UserMailer.password_reset(self).deliver
  end

  private

    def create_remember_token
      self.remember_token = User.digest(User.new_remember_token)
    end

    def confirmation_token
      # only generate if you did not manually set value
      if self.confirm_token.blank?
          self.confirm_token = SecureRandom.urlsafe_base64.to_s
      end
    end
end

和我的用户控制器:

class UsersController < ApplicationController
  before_action :signed_in_user, only: [:index, :edit, :update, :destroy, :following, :followers]
  before_action :correct_user,   only: [:edit, :update]
  before_action :admin_user,     only: :destroy
  before_action :registered_already, only: [:new, :create]

  def index
    @users = User.paginate(page: params[:page])
  end

  def show
    @user = User.find(params[:id])
    @microposts = @user.microposts.paginate(page: params[:page])
  end

  def new
      @user = User.new
  end

  def create
        @user = User.new(user_params)    
      if @user.save
        UserMailer.registration_confirmation(@user).deliver
        flash[:success] = "Please confirm your email address to continue"
        redirect_to root_url
      else
        flash[:error] = "Ooooppss, something went wrong!"
        render 'new'
      end
  end

  def edit
  end

  def update
    if @user.update_attributes(user_params)
      flash[:success] = "Profile updated"
      redirect_to @user
    else
      render 'edit'
    end
  end

  def destroy
    user = User.find(params[:id])
    unless current_user?(user)
      user.destroy
      flash[:success] = "User deleted."
    end
    redirect_to users_url
  end

  def following
    @title = "Following"
    @user = User.find(params[:id])
    @users = @user.followed_users.paginate(page: params[:page])
    render 'show_follow'
  end

  def followers
    @title = "Followers"
    @user = User.find(params[:id])
    @users = @user.followers.paginate(page: params[:page])
    render 'show_follow'
  end

  def confirm_email
    user = User.find_by_confirm_token(params[:id])
    if user
      user.email_activate
      flash[:success] = "Welcome to the Sample App!"
      redirect_to root_url
    else
      flash[:error] = "Sorry. User does not exist"
      redirect_to root_url
    end
  end

   private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end

    # Before filters

    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_url) unless current_user?(@user)
    end

    def admin_user
      redirect_to(root_url) unless current_user.admin?
    end

    def registered_already
      redirect_to root_url, notice: "You are already registered." if signed_in?
    end

end

我的会话控制器

class SessionsController < ApplicationController

  def new
  end

  def create
      user = User.find_by_email(params[:email].downcase)
      if user && user.authenticate(params[:password])
      if user.email_confirmed
          sign_in user
        redirect_back_or user
      else
        flash.now[:error] = 'Please activate your account by following the 
        instructions in the account confirmation email you receieved to proceed'
      end
      else
        flash.now[:error] = 'Invalid email/password combination' # Not quite right!
        render 'new'
      end
  end

  def destroy
    sign_out
    redirect_to root_url
  end
end 

我觉得用户模型中的email_activate方法是在创建操作上调用的,但我不知道为什么?....

就在我这样做的时候,我注释掉了`:unless =&gt; :email_activate&#39;在密码验证器中。现在一切正常。令我感到惊讶的是,这就是原因,因为它对我对轨道的理解(通常有些限制)没有逻辑意义。有人可以解释为什么这会将电子邮件确认字段设置为真吗?

1 个答案:

答案 0 :(得分:0)

如果要始终设置默认值,则不能允许空值。指定:null => false

add_column :users, :email_confirmed, :boolean, :null => false, :default => false