使用现有值进行验证

时间:2011-07-31 23:38:08

标签: ruby-on-rails ruby ruby-on-rails-3

我有一个主题模型:

class Topic < ActiveRecord::Base
  belongs_to :user

  def validate_on_update
    errors.add(:user, "Only the topic creator can update the topc") if
      self.user != user;
  end
end

我想在每次更新之前检查现有的topic.user与尝试更新模型的用户是否相同。

我认为

self.user != user 

无效,但我不知道如何解决这个问题!

1 个答案:

答案 0 :(得分:1)

在执行此操作之前,您需要在控制器中找到记录,因此您可以在控制器操作中执行此操作:

@topic = current_user.topics.find(params[:id])

这将触发您可以轻松捕获或离开的异常。

这是确保数据完整性的最佳方法,除非您在应用程序的其他位置进行修补,并且您需要创建不在控制器中的主题。

如果您有这样的需求,在模型中设置验证规则以确保主要数据完整性并不坏,但模型确实需要知道用户,只能从控制器访问。

我的建议是指定用户控制器端或仅使用范围:

current_user.topics.create(params[:topic])

通过这种方式,您可以确定该用户是相同的,如果这是您调用主题创建的唯一位置,则无需再进行其他验证。

如果您不确定并希望使用validate_on_update进行游戏,我建议您创建一个虚拟属性:

attr_accessor :this_user

但无论如何你都会通过控制器传递这个,因为你的模型应该对当前登录的用户一无所知:

@topic = Topic.new(params[:topic])
@topic.this_user = current_user # or @topic.user_id and check for a attr_changed?

更新:按要求添加示例

# @topic = Topic.new(params[:topic])
# @topic.this_user = current_user

class Topic < ActiveRecord::Base
  belongs_to :user
  attr_accessor :this_user

  def validate_on_update
    # Make sure that this_user is an instance of User, otherwise just use the id
    errors.add(:user, "Only the topic creator can update the topic") if user_id != this_user.id;
  end
end

<强>更新

另一个建议是使用:

attr_readonly :user_id