我在用户和文档之间有多对多的关系。用户可以通过输入他们的电子邮件邀请其他用户协作处理他们的文档。应用程序将通过电子邮件查找用户并在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
答案 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