атрибуты и конструкторы в рельсах - PullRequest
4 голосов
/ 08 января 2010

Я новичок в рельсах и даже не знаю, правильный ли это способ решения моей ситуации.

У меня есть модель "Club" ActiveRecords, которая имеет ассоциацию "has_many" с моделью "Member". Я хочу, чтобы вошедший в систему «Клуб» мог администрировать только своего «члена», поэтому в начале каждого действия в модели «Участник» я делал что-то похожее на следующее:

def index
 @members = Club.find(session[:club_id]).members

для доступа к нужным участникам. Это, однако, оказалось не очень СУХОЙ, как я делал то же самое в каждом действии. Поэтому я подумал об использовании чего-то, эквивалентного тому, что будет называться конструктором в других языках. Метод инициализации, как я понял. Это, однако, не работало, это объяснило мне почему и предложило альтернативу. After_initialize.

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

def index
 @members = @club.members
....

, похоже, не работает в любом случае. Есть какие-нибудь указатели на то, почему?

You have a nil object when you didn't expect it!
The error occurred while evaluating nil.members

Заставляет меня думать, что @club var вообще не установлен.

Кроме того, действительно ли это решение хорошее? Это затрудняет реализацию любого «супер администратора», который может управлять членами во всех клубах. Любые идеи о том, где я что-то упускаю?

Ответы [ 3 ]

5 голосов
/ 08 января 2010

Вы можете использовать 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

Затем загрузите фильтр перед любым действием, в котором он вам нужен. Например

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

  def index
    # here @members is set
  end
end

В противном случае используйте ленивую загрузку. Вы можете использовать тот же load_members и вызывать его в любое время.

class ClubController < ApplicationController
  def index
    # do something with members
    load_members.each { ... }
  end
end

Конечно, вы можете настроить load_member, чтобы вызвать исключение, перенаправить клиента, если @members.empty?, или делать все, что вы хотите.

3 голосов
/ 08 января 2010

Вы хотите использовать для этого before_filter .

class MembersController < ApplicationController

  before_filter :find_club

  def index
    @members = @club.members
  end

  private

    def find_club
      @club = Club.find(session[:club_id])
    end
end
0 голосов
/ 08 января 2010

Я фанат плагина под названием Rolerequirement. Это позволяет вам создавать собственные роли и применять их по контроллеру: http://code.google.com/p/rolerequirement/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...