我坚持定义一种自定义验证方法,其目的是验证两个模型中属性的唯一性
我意识到这是错误的代码,但我想在重构之前通过测试
这是一个带有自定义验证的模型,用于检查另一个模型属性,错误未定义的局部变量或方法`params' (要温柔,我还在努力弄清楚RoR)
class Widget < ActiveRecord::Base
include Slugable
validates :name, presence: true
validate :uniqueness_of_a_slug_across_models
def uniqueness_of_a_slug_across_models
@sprocket = Sprocket.where(slug: params[:widget_slug]).first
if @sprocket.present?
errors.add(:uniqueness_of_a_slug_across_models, "can't be shared slug")
end
end
end
答案 0 :(得分:1)
您无法访问模型中的params
。它属于controller和view。您可以做的是在窗口小部件控制器(而不是常规save
)中调用自定义方法,以便将params传递给模型:
class WidgetsController < ActionController::Base
def create
@widget = Widget.new(widget_params)
if @widget.save_with_slug_validation(params)
redirect_to widgets_path
else
render :new
end
end
end
并定义它:
class Widget < ActiveRecord::Base
# ...
def save_with_slug_validation(params)
sprocket = Sprocket.find_by(slug: params[:widget_slug])
if sprocket
errors.add(:uniqueness_of_a_slug_across_models, "can't be shared slug")
end
save
end
end
我没有测试它,但它应该有用。
P.S。使用Rails 4样式。
我应该测试一下,抱歉。请使用其他方法。
小部件控制器:
# POST /widgets
# POST /widgets.json
def create
@widget = widget.new(widget_params)
@widget.has_sprocket! if Sprocket.find_by(slug: params[:widget_slug])
respond_to do |format|
if @widget.save
format.html { redirect_to [:admin, @widget], notice: 'widget was successfully created.' }
format.json { render action: 'show', status: :created, location: @widget }
else
format.html { render action: 'new' }
format.json { render json: @widget.errors, status: :unprocessable_entity }
end
end
end
小工具模型:
class Widget < ActiveRecord::Base
include Slugable
validates :name, presence: true
validate :uniqueness_of_a_slug_across_models, if: 'has_sprocket?'
def uniqueness_of_a_slug_across_models
errors.add(:uniqueness_of_a_slug_across_models, "can't be shared slug")
end
def has_sprocket!
@has_sprocket = true
end
def has_sprocket?
!!@has_sprocket
end
end
最好移动has_sprocket!
和has_sprocket?
方法,并将其自身验证为Slugable
关注点。