Отфильтрованные по владельцу объекты модели в Rails 3

Мне нужно сделать некоторую фильтрацию на моих моделях ActiveRecord, я хочу отфильтровать все мои объекты модели по owner_id. Что мне нужно, так это в основном default_scope для ActiveRecord.

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

Это моя декларация по объему:

class MyModel < ActiveRecord::Base
    default_scope { where(:owner_id => session[:user_id]) }
    ...
end

Просто, правда? Но это не говорит о том, чтоmethod session does not exists.

Надеюсь, вы можете помочь

 John Plummer21 мая 2012 г., 10:10
Есть ли причина, по которой вы не хотите иметь объект-владелец с ассоциациями?
 Rubén T.F.21 мая 2012 г., 14:22
Хммммм ... хорошая точка зрения, завтра попробую, сейчас не время. Спасибо за отве

Ответы на вопрос(3)

связанная с сеансом, является задачей пользовательского интерфейса, поэтому она имеет свое место в контроллере. (Классы моделей не имеют доступа к циклу запросов, сеансу, файлам cookie и т. Д.).

То, что ты хочешь, это

# my_model_controller.rb
before_filter :retrieve_owner_my_models, only => [:index] # action names which need this filtered retrieval

def retrieve_owner_my_models
   @my_models ||=  MyModel.where(:owner_id => session[:user_id])
end

Поскольку фильтрация по владельцу текущего пользователя является типичным сценарием, возможно, вы могли бы подумать об использовании стандартных решений, таких как поиск 'cancan gem, available_by'

Также надо знать о зле default_scope. rails3 default_scope и значение столбца по умолчанию в миграции

 Rubén T.F.21 мая 2012 г., 13:57
IMHO, это не заменяет default_scope: при создании нового объекта не устанавливается установленный owner_id, при выполнении сложных поисков он не фильтруется автоматически по owner_id ... Область default_scope намного более автоматическая.
 Viktor Trón21 мая 2012 г., 15:03
1. Бизнес-логика в дизайне MVC отделена от пользовательского интерфейса, то есть модели могут использоваться в пользовательских интерфейсах без сеанса. Таким образом, такая передача прав собственности зарегистрированным пользователям является обязанностью контроллера. 2) автоматическая фильтрация владельцев по умолчанию - плохой дизайн: например, интерфейс администратора, извлекающий продукты для всех владельцев или частей вашего кода, когда вы фактически манипулируете MyModel-s. 3. default_scope лучше всего использовать для установки естественных порядков и состояний по умолчанию (: active => true), но даже это лучше всего делать в схеме controller, initializer и db schema. Это делает рельсы default_scope спорными на мой взгляд.

ование (например, в консоли), так как сеанс отсутствует.

Что вы можете сделать: добавьте метод для вашего ApplicationController, как этот

class ApplicationController
  ...
  def my_models
    Model.where(:owner_id => session[:user_id])
  end
  ...

  # Optional, for usage within your views:
  helper_method :my_models
end

Этот метод все равно вернет область видимости.

Решение Вопроса

вместо этого вы должны добавить атрибут класса кUser класс, который вы установили вaround_filter в вашемApplicationController, основываясь на текущем пользователе

class User < ActiveRecord::Base

    #same as below, but not thread safe
    cattr_accessible :current_id

    #OR

    #this is thread safe
    def self.current_id=(id)
      Thread.current[:client_id] = id
    end

    def self.current_id
      Thread.current[:client_id]
    end  

end

и в твоемApplicationController делать

class ApplicationController < ActionController::Base
    around_filter :scope_current_user  

    def :scope_current_user
        User.current_id = current_user.id
    yield
    ensure
        #avoids issues when an exception is raised, to clear the current_id
        User.current_id = nil       
    end
end

А теперь в твоемMyModel вы можете сделать следующее:

default_scope where( owner_id: User.current_id ) #notice you access the current_id as a class attribute
 Sravan28 мая 2016 г., 09:09
Привет, что такое «Thread» и «client_id» выше.
 scanales30 мая 2016 г., 17:58
Thread ссылается на текущий поток. Проверьте здесь на его безопасность: / Stackoverflow.com вопросы / 7896298 / ... а такжеclient_id является атрибутомUser модель, которая используется вdefault_scope
 Rubén T.F.08 мар. 2013 г., 11:04
Хммм, мне это нравится. Я проверю это на моем следующем проекте, спасибо!
 scanales08 мар. 2013 г., 19:16
@ RubénT.F. круто, надеюсь, вы найдете это полезным

Ваш ответ на вопрос