Rails 4 - nil的未定义方法'attributes':NilClass

时间:2014-04-17 16:22:57

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

我在用户和文档之间有多对多的关系。用户可以通过输入他们的电子邮件邀请其他用户协作处理他们的文档。应用程序将通过电子邮件查找用户并在DocumentUser中设置user_id。如果找不到用户,我收到此错误:Rails 4 - nil的未定义方法'attributes':NilClass。 DocumentUsersControlller.create中发生此错误。如何使用最佳做法防止此错误?另外,为什么存在验证器不能防止此错误?

以下是相关的控制器和型号:

class DocumentUsersController < ApplicationController

  def new
    @document = Document.find_by link_key: params[:document_id]
    @document_user = @document.document_users.build
  end

def create

  @document = Document.find_by link_key: params[:document_id]
  @document_user = @document.document_users.build(document_user_params)
  user = User.find_by email: params[:document_user][:email]  
  @document_user.user = user if user

  respond_to do |format|
      if @document_user.save  #error occurs here if user is Nil
          format.html { redirect_to @document, notice: 'User Invitation was sent.'}
          format.json { render action: 'show', status: :created, location: @document_user }
      else
          format.html { render action: 'new' }
          format.json { render json: @document_user.errors, status: :unprocessable_entity }
      end

  end
end

def destroy
end

private

def document_user_params
    params.require(:document_user).permit(:email, :admin, :editor, :viewer)
end

end


class DocumentUser < ActiveRecord::Base
  include KeyCreator

  belongs_to :document
  belongs_to :user
  before_create :before_create

    attr_accessor :email

    validates :user, uniqueness: { message: "has already been invited" }
    validates :user, presence: true
    validate :email_matches_user

    def to_param
        "#{invite_key}".parameterize
    end

 private

    def before_create
        now = DateTime.now      
        self.added_date = now
        self.modified_date = now
        self.invite_key = create_key
        self.api_key = create_key
    end

   def email_matches_user
       unless User.exists? email: email 
           errors.add(:email, "does not match any existing user")
       end
   end

end


class User < ActiveRecord::Base
    include KeyCreator

    # Include default devise modules. Others available are:
    # :confirmable, :lockable, :timeoutable and :omniauthable
    devise :database_authenticatable, :registerable, :confirmable, 
     :recoverable, :rememberable, :trackable, :validatable

has_many :document_users
has_many :documents, :through => :document_users
before_create :before_create

private

    def before_create
        self.api_key = create_key
    end

end


class Document < ActiveRecord::Base
     include KeyCreator

has_many :document_users, dependent: :destroy
    has_many :users, :through => :document_users
    before_create :before_create

    def self.created_by(user)
        Document.joins(:document_users).where(:document_users => {:user => user, :creator => true}).order(:name)
    end

    def self.guest_in(user)
        Document.joins(:document_users).where(:document_users => {:user => user, :creator => false}).order(:name)
    end

    def to_param
        "#{link_key}".parameterize
    end

private

    def before_create
        now = DateTime.now
        self.content = nil
        self.created_date = now
       self.modified_date = now
       self.deleted_date = nil
       self.api_key = create_key
       self.link_key = create_key
    end

end

1 个答案:

答案 0 :(得分:3)

更改您的email_matches_user。它应该匹配
email:self.email

def email_matches_user
   unless User.exists? email: self.email 
       errors.add(:email, "does not match any existing user")
   end
end