类变量是在Rails应用程序中为类实例设置上下文的好方法吗?

时间:2012-01-27 02:47:08

标签: ruby-on-rails

类变量是否是在Rails应用程序中为类实例设置上下文的好方法?

我们正在构建一个管理俱乐部成员的rails应用程序。因此,有会员模型和俱乐部模型。由于会员可以属于许多俱乐部,俱乐部可以有很多会员,因此他们之间有HABTM协会。

我们遇到的困难是确定成员实例存在的俱乐部上下文。例如,要将会员会费状态设置为“付费”,我们需要知道会员已支付会费。我们希望控制器只需设置类似

的内容
@member.paid=true  

每次我们更新会员时都不必为记得设置俱乐部而烦恼。

我们提出的解决方案在Member中设置了一个类变量。

application_controller.rb
class ApplicationController < ActionController::Base

  before_filter :set_current_club

  def set_current_club
    Member.current_club = current_club
  end

  ...

end

作为一个有点人为的例子,想象一下每个俱乐部都包含一系列缴纳会费的会员。那我们就有了。

member.rb
class Member < ActiveRecord::Base

  cattr_accessor :current_club

  ...

  def paid=(status)
    if (status)
      @@current_club.paid_members << self
    else
      @@current_club.paid_member.delete(self) 
    end
  end

  def paid?
    @@current_club.paid_members.include?(self)
  end

  ...

end

担心的是,通过在ApplicationController before_filter中将current_club设置为Member类变量,当多个俱乐部同时访问应用程序时,是否可能存在冲突和竞争条件?

我们在开发环境中进行了一些调试测试,并且在ApplicationController中输入before_filter方法时,模型(Member.current_club)中的@@ current_club属性始终为nil。换句话说,没有证据表明current_club在提供新请求时受到先前请求的影响。所以我认为我们没问题,从Application Controller设置模型类变量的范围是用户的会话。但在继续这种方法之前,我想确定一下。“

1 个答案:

答案 0 :(得分:0)

如果你有current_club属性,我假设它是某种形式的会话变量,那么完全不需要上面的代码。

要在拥有current_club变量的同时获取会员的俱乐部记录,只需遍历与该会员相关的所有俱乐部,找到与当前俱乐部相匹配的记录即可。

这样的事情:

class Member < AR::Base
  def paid_for(club, status)
    if status
      club.paid_members << self
    else
      club.paid_members.delete(self)
    end
  end

你不需要担心竞争条件,由于价值悬浮而产生的怪异以及所有废话。