【问题标题】:rails pass variable from model to another controllerrails 将变量从模型传递到另一个控制器
【发布时间】:2015-12-30 09:21:02
【问题描述】:

我有一个 rails 项目,我想将一个变量从我的用户模型传递到另一个控制器。

我该怎么做?我知道这不是最好的方法,但我想不出任何其他方法来解决我的问题。

我正在使用 Devise 登录,如果由于用户被锁定而导致登录失败,我想显示一个链接。

在我的用户模型中,我有这个方法

def after_database_authentication
  update_attributes!(password_changed_at: self.last_activity_at)
  user_locked = self.is_locked
end

我想在我的 Post 控制器中添加这个变量 user_locked

所以在我的 Post 控制器方法中是新的,我想在这里使用它

def new 
  ap user_locked
end

觉得我能做到这一点的唯一方法是使用会话,但不能在 rails 模型中分配会话变量。

任何其他选项将不胜感激。谢谢

【问题讨论】:

  • user_locked 是数据库列吗?
  • 不,它不是数据库列

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


【解决方案1】:

当您使用 Devise 时,您可以使用辅助方法 current_user。那么为什么不使用这样的解决方案呢?

class User
  def locked?
    is_locked
  end
end

UserController
  def new
    current_user.locked?
  end
end

【讨论】:

    【解决方案2】:

    我认为您对 MVC 结构感到困惑。

    您的model 是一个由数据库数据填充的类,或者具有 方法/变量形式的预定义数据。

    因此,当你问......

    我想将一个变量从我的用户模型传递到另一个控制器

    ...上下文完全不正确。


    型号

    如果你想通过你的模型传递一个,你要么将它存储在数据库中(这样模型的属性之一就填充了值),要么你将它存储作为类级别的值:

    #app/models/user.rb
    class User < ActiveRecord::Base
       def is_locked?
          true #-> User.new.is_locked? -> true
       end
    
       def self.is_locked?
          false #-> User.is_locked? -> false
       end
    end
    

    根据您所写的内容,我强烈建议将is_locked 设为数据库属性:

    $ rails g migration AddIsLockedToUsers
    
    # db/migrate/add_is_locked_to_users________.rb
    class AddIsLockedToUsers < ActiveRecord::Migration
       def change
          add_column :users, :is_locked, :boolean, default: false
       end
    end
    
    $ rake db:migrate
    

    这会将is_locked? 值设置为User 模型的属性,这意味着每次调用User 时,您都可以检查它们是否是是否锁定:

    #app/controllers/posts_controller.rb
    class PostsController < ApplicationController
       def new
          @user = User.find params[:user_id]
          redirect_to root_path if @user.is_locked?
       end
    end
    

    --

    除此之外,您可能希望使用ActiveRecord::Observerafter_update 回调来更新锁定状态:

    #app/models/user.rb
    class User < ActiveRecord::Base
       after_update :set_locked, if: "password_changed_at.changed?"
    
       private
    
       def set_locked
          self.is_locked = true
       end
    end
    

    【讨论】:

    • 我实际上并没有感到困惑,这有 nthg 要做 wt is_locked 属性。也许我没有解释清楚..我在我的登录页面上显示一个链接。 d 链接只能在登录失败时显示。 d 在我的会话/新视图上知道用户登录是否失败的唯一方法是检查 user.is_locked 是否为真。但是由于在会话/新上我没有任何 current_user,唯一的检查方法是在模型中保存一个全局会话变量,我可以检查会话/新以显示我的链接。我希望这能让它更清楚一点。
    猜你喜欢
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多