rails中的属性和构造函数

Fel*_*sen 4 ruby ruby-on-rails

我是铁杆新手,甚至不知道这是否是解决我情况的正确方法.

我有一个"俱乐部"ActiveRecords模型,它与"会员"模型有"has_many"关联.我希望登录的"俱乐部"只能管理它自己的"会员",所以在"会员"模型的每个动作的开头,我做了类似以下的事情:

def index
 @members = Club.find(session[:club_id]).members
Run Code Online (Sandbox Code Playgroud)

访问正确的成员.然而,这并没有因为我在每个动作中做同样的事情而变得非常干燥.所以我想到使用与其他语言中的构造函数等效的东西.正如我所理解的那样初始化方法.然而这不起作用,告诉我为什么,并提出了另一种选择.after_initialize.

def after_initialize
 @club = Club.find(session[:club_id])
end

def index
 @members = @club.members
....
Run Code Online (Sandbox Code Playgroud)

似乎无论如何都不起作用.任何指针为什么?

You have a nil object when you didn't expect it!
The error occurred while evaluating nil.members
Run Code Online (Sandbox Code Playgroud)

让我觉得@club var根本没有设置.

此外,这个解决方案真的很好吗?这使得很难实现任何一种能够管理所有俱乐部成员的"超级管理员".关于我遗失某些东西的任何想法?

Sim*_*tti 5

你可以使用before_filter.在ApplicationController中定义过滤器(以便您可以从任何控制器访问它).

class ApplicationController < ActionController::Base

  # ..

  protected

    def load_members
      @members = if session[:club_id]
        Club.find(session[:club_id]).members
      else
        []
      end
    end

end
Run Code Online (Sandbox Code Playgroud)

然后,在您需要的任何操作之前加载过滤器.例如

class ClubController < ApplicationController
  before_filter :load_members, :only => %w( index )

  def index
    # here @members is set
  end
end
Run Code Online (Sandbox Code Playgroud)

否则,请使用延迟加载.您可以使用load_members它并在需要时随时调用它.

class ClubController < ApplicationController
  def index
    # do something with members
    load_members.each { ... }
  end
end
Run Code Online (Sandbox Code Playgroud)

当然,您可以自定义load_member以引发异常,重定向客户端,@members.empty?无论您想做什么或做什么.