【问题标题】:@variables in rails from Application Controller来自应用程序控制器的导轨中的@variables
【发布时间】:2013-12-04 22:21:28
【问题描述】:

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

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

我想使用“default_scope”,因为对 DB 的任何查询都应该注意用户想要查看的频道。

应用控制器

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

型号

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

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


      default_scope {where.not(ctype: @user_ctypes)}

用户(设计者)

class User < ActiveRecord::Base

【问题讨论】:

  • 您无法访问模型中的实例变量...
  • 渠道和用户之间有什么关系吗?
  • 我建议不要使用unless/else,而是更改代码以便您可以使用if/else。它将提高代码的可读性。
  • @MichaelStalker 好的,谢谢。
  • @JasdeepSingh 不,没有关系

标签: ruby-on-rails ruby ruby-on-rails-4


【解决方案1】:

控制器(在这种情况下是您的ApplicationController)和模型(在这种情况下是Channel)是不同对象的不同实例,因此不共享实例变量,因此您不能在型号。

通常,要将变量传递到作用域中,您通常会执行以下操作:

scope :name lambda{|user_ctypes| { where.not(ctype: user_ctypes) }

问题来了,这是一个默认作用域,所以你不能真正与它共享在控制器中创建的实例变量,否则它有点像全局变量。

考虑看看这一点,看看是否有更好的方法来做到这一点,我总是在 Rails 中发现,如果很难做到/不可行,那可能是错误的。也许您可以考虑使用普通范围或将您的逻辑移到其他地方。

【讨论】:

  • 在 ApplicationController 中设置 session[:user_ctypes] 而不是 @user_ctypes 应该更好?因为我尝试过,但我在模型 default_scope {where.not(ctype: session[:user_ctypes])} 中得到了未定义的局部变量或方法“会话”
  • 它也不起作用 - 模型对象无权访问会话,只能在控制器、助手和视图中使用。
  • @user1028100 eugen 是对的,这又是一回事。也许给我们一些上下文,使用的范围在哪里等等,看看我们是否可以帮助重构它。
  • 非常感谢。那么current_user.ctypes,有Ctype模型吗?我认为用户和频道之间的习惯关系最有意义,如果有这个Ctype 模型,可以稍微修改一下。我猜不是,但也许我们很幸运 :) 忽略它实际上不起作用,我可以看到你所做的事情“更容易”,但这里有两个 db 调用,它只是没有可扩展性,可能会有一些功能会受到此阻碍。所以是的,Ctype 是一个模型还是只是用户模型中的一个数组?
【解决方案2】:

发生这种情况是因为您将已声明 @user_ctypes 变量的方法设置为 private

【讨论】:

    猜你喜欢
    • 2012-09-23
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 1970-01-01
    相关资源
    最近更新 更多