Как всегда установить значение для учетной записи в Rails? - PullRequest
4 голосов
/ 27 апреля 2009

Я работаю над многопользовательским приложением с несколькими учетными записями, где 1 учетная запись может иметь n пользователей Очень важно, чтобы каждый пользователь мог получить доступ только к информации из своего аккаунта. Мой подход заключается в том, чтобы добавить account_id к каждой модели в БД, а затем добавить фильтр в каждом контроллере для выбора только объектов с текущим account_id. Я буду использовать плагин авторизации.

Является ли этот подход хорошей идеей?

Каков наилучший способ всегда устанавливать account_id для каждого объекта, который создается без записи

object.account = @current_account

в каждом действии CREATE? Может быть, фильтр?

Также я не уверен в том, как лучше применить фильтр для выбранных параметров. Мне нужно что-то вроде общего условия: независимо от того, что еще появляется в операторе SQL, всегда есть «WHERE account_id = XY».

Спасибо за вашу помощь!

Ответы [ 4 ]

4 голосов
/ 27 апреля 2009

Это похоже на сценарий User.has_many: emails. Вы не хотите, чтобы пользователь видел электронные письма других людей, изменив идентификатор в URL, поэтому вы делаете это:

@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])
1 голос
/ 11 ноября 2009

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

Чтобы добавить немного магии и сделать это без проблем, взгляните на следующий драгоценный камень

http://gemcutter.org/gems/account_scopper

Надеюсь, это поможет,

- Себастьян Грожан - ZenCocoon

1 голос
/ 27 апреля 2009

Чтобы ответить на второй вопрос, ознакомьтесь с новой функцией default_scope в Rails 2.3.

1 голос
/ 27 апреля 2009

Я знаю, я знаю, если вы обращаетесь к переменным сеанса или переменным экземпляра в вашей модели, вы не понимаете шаблон 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

Вы также можете работать с чем-то вроде обратного вызова before_validation в active_record, а затем сделать с проверкой, что учетная запись всегда установлена.

Тот же подход можно использовать, если вы всегда хотите добавить current_user к каждому созданному объекту.

Что вы думаете?

...