4

我正在开发一个多用户、多帐户应用程序,其中 1 个帐户可以有 n 个用户。每个用户只能从其帐户访问信息,这一点非常重要。我的方法是为数据库中的每个模型添加一个 account_id,然后在每个控制器中添加一个过滤器以仅选择具有当前 account_id 的对象。我将使用授权插件。

这种方法是个好主意吗?

什么是最好的方法来始终为每个创建的对象设置 account_id 而无需编写

object.account = @current_account

在每个 CREATE 动作中?也许是过滤器?

此外,我不确定为选择选项实施过滤器的最佳方法。我需要一个类似一般条件的东西:无论 SQL 语句中出现什么其他内容,总有一个“WHERE account_id = XY”。

谢谢你的帮助!

4

4 回答 4

4

这类似于 User.has_many :emails 场景。您不希望用户通过更改 URL 中的 ID 来查看其他人的电子邮件,因此您可以这样做:

@emails = current_user.emails

在您的情况下,您可能可以执行以下操作:

class ApplicationController < ActionController::Base
  def current_account
    @current_account ||= current_user && current_user.account
  end
end

# In an imagined ProjectsController
@projects = current_account.projects
@project = current_account.projects.find(params[:id])
于 2009-04-27T07:16:38.583 回答
1

我知道,我知道,如果您在模型中访问会话变量或实例变量,那么您不了解 MVC 模式并且“应该回到 PHP”。但是,如果您像我们一样拥有很多控制器和操作,但您并不总是想编写 @current_account.object.do_something(不是很干),这仍然非常有用。

我找到的解决方案非常简单:

第 1 步:将您的 current_account 添加到 Thread.current,例如

class ApplicationController < ActionController::Base
  before_filter :get_current_account      

  protected
   def get_current_account
     # somehow get the current account, depends on your approach
     Thread.current[:account] = @account
   end
end

第 2 步:为所有模型添加 current_account 方法

   #/lib/ar_current_account.rb
   ActiveRecord::Base.class_eval do
     def self.current_account
      Thread.current[:account]
     end
   end

第 3 步:瞧,在您的模型中,您可以执行以下操作:

class MyModel < ActiveRecord::Base

  belongs_to :account

  # Set the default values
  def initialize(params = nil) 
    super
      self.account_id ||= current_account.id
  end

end

您还可以使用 active_record 中的 before_validation 回调之类的东西,然后通过验证确保始终设置帐户。

如果您总是想将 current_user 添加到每个创建的对象,则可以使用相同的方法。

你怎么看?

于 2009-04-27T07:59:05.440 回答
1

要回答您的第二个问题,请查看default_scopeRails 2.3 中的新功能。

于 2009-04-27T08:30:17.580 回答
1

我知道您不想一直为您的帐户范围而烦恼。老实说,这是一个痛苦的**。

要添加一点魔力并无缝完成此范围界定,请查看以下 gem

http://gemcutter.org/gems/account_scopper

希望这可以帮助,

-- 塞巴斯蒂安·格罗斯让 - ZenCocoon

于 2009-11-11T11:45:54.693 回答