@Variables来自Application Controller的rails

spa*_*kle 0 ruby ruby-on-rails ruby-on-rails-4

我设置了@user_ctypes,但是当我从模型访问它时,我得到一个Nil值.为什么?

这是电视指南,用户(current_user)将设置要隐藏的频道.例如:如果登录的用户没有卫星,他将拥有ctypes = ['sat'].因此,任何在卫星上播出的频道都将隐藏给用户.如果未记录用户,则current_user为nil.

我想使用"default_scope",因为对DB的任何查询都应该注意用户想要查看的通道.

ApplicationController的

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

  before_filter :set_user_ctypes


  private

  def set_user_ctypes
    unless current_user.nil? 
      @user_ctypes = current_user.ctypes 
    else
      @user_ctypes =  Array.new
    end
  end
Run Code Online (Sandbox Code Playgroud)

模型

 class Channel < ActiveRecord::Base
      has_many :programs, :dependent => :delete_all

       validates :name, :site, :ctype, :country, :presence => true


      default_scope {where.not(ctype: @user_ctypes)}
Run Code Online (Sandbox Code Playgroud)

用户(由Devise提供)

class User < ActiveRecord::Base
Run Code Online (Sandbox Code Playgroud)

Nia*_*son 5

控制器(ApplicationController在本例中为您的)和模型(Channel在本例中)是不同对象的不同实例,因此不共享实例变量,因此您无法在模型中使用实例变量.

通常,要将变量传入范围,通常会执行以下操作:

scope :name lambda{|user_ctypes| { where.not(ctype: user_ctypes) }
Run Code Online (Sandbox Code Playgroud)

这是问题,这是一个默认范围,因此您无法真正共享在控制器中创建的实例变量,因为否则它有点像全局变量.

考虑一下这个位,看看是否有更好的方法,我总是发现Rails,如果很难做到/不可行,那可能是错的.也许您可以考虑使用正常范围或在其他地方移动逻辑.