如何同时处理Rails中的非持久和持久关联对象?

时间:2011-07-13 17:41:03

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

我会尽力解释这个问题。所以,我跳过了任何不必说明问题的代码。

我们假设一个模型:

class Model < ActiveRecord::Base

  # Join class storing grants for users, e.g. 'admin', 'default'
  has_many :user_grants

  # Grant a user a certain grant
  def grant_user(user, grant)
    self.user_grants.build(:user => user, :grant => grant)
  end

  # Some action is done by a user, but ensure user has required grants
  def action(user, action_type)
     unless user_grants.find_by_user_id_and_grant(user, GrantEnum::ADMIN)
        raise ModelUserNotAllowedError.new
     end
     ...action code...
  end

我跳过了User和其他一些模型的代码,因为它们与说明无关......

我们实例化代码:

  1: @model = Model.new
  2: @user = User.new
  3: @model.grant_user(@user, GrantEnum::ADMIN)
  4: @model.action(@user, ActionEnum::SOMETHING)

第4行将引发ModelUserNotAllowedError,因为此时第3行中所需的授权构建不会保留,但finder方法仅适用于持久数据。从逻辑的角度来看,不应该引发错误,因为用户被授予了足够的权限。

我正在使用 self.user_grants.build ,因为调用grant_user时可能不会保留模型。

那么,有什么选择可以让它发挥作用:

1。)实现仅使用 association.create 而不是 association.build 的代码,以确保查找程序方法是“最新的”。这也需要先拯救父母。

2.。)实现代码,通过使用 finder方法检查持久化数据,并通过循环检查来检查非持久数据,例如:鉴于上面的例子,可以检查非持久数据:

  user_grants.each do |user_grant|
    if user_grant.grant.eql?(GrantEnum::ADMIN)
      return true
    end
  end

然而,提案号2似乎是一个坏主意。所以,让我们忘记吧......

还有其他选择吗?例如有没有办法让finder方法检查非持久数据?希望得到一些新的见解...

1 个答案:

答案 0 :(得分:0)

unless user_grants.select {|user_grant| user == user && grant == GrantEnum::ADMIN}.present?
        raise ModelUserNotAllowedError.new
end