【问题标题】:Defining instance variables in rails controllers [duplicate]在rails控制器中定义实例变量[重复]
【发布时间】:2018-12-20 08:17:46
【问题描述】:

我在执行Hartl's Tutorial 时遇到了 2 个非常相似的代码。在代码清单 8.25 中,show 返回了一个实例变量 @user,它是通过 Rails 的 find 方法获得的。

class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      log_in @user
      flash[:success] = "Welcome to the Sample App!"
      redirect_to @user
    else
      render 'new'
    end
  end

  private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end
end

在代码清单 8.30 中,create 也有类似的情况,它使用了find_by,也应该返回一个实例变量,但这次它被定义为user 而不是@user。我真的不知道什么时候使用@,而且我还观察到两者都是控制器,所以我认为语法应该是一致的。这种差异是否有原因?一般来说,我们何时允许或不允许使用@ 定义实例变量?

class SessionsController < ApplicationController

  def new
  end

  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      redirect_to user
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end

  def destroy
    log_out
    redirect_to root_url
  end
end

我的一个附带问题是,我是否可以得出结论,控制器中定义的任何方法都绝对是类方法,因此需要User.new,而在我们需要定义方法的模型中,由于额外的提供了灵活性,我们需要在实现过程中明确声明它是类方法def User.new_token还是实例方法(def remember)。

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    在这种情况下,例如,在users#new 中定义实例变量对于在视图中可访问是必要的。 Rails 使用这种特定机制将控制器上下文中定义的所有实例变量复制到视图中。

    另一方面,在sessions#create 中,您只想在登录成功时重定向用户,否则显示登录表单,正如您在sessions#new 中看到的那样,不需要定义任何实例变量。所以在这种情况下局部变量就足够了。

    【讨论】:

    • 您好,感谢您的回答,在合并您的两个答案后,我对替代答案发表了评论。你介意验证我的假设的正确性吗?
    【解决方案2】:

    大部分情况下我们需要使用实例变量,

    1. 当我们需要从视图中访问变量时
    2. 如果我们从动作中调用一个方法,而不是返回一个值,我们可以直接从被调用的方法中更新变量。

    请不要混淆 user 是一个局部变量。它们只存在于其范围内(当前块)

    @user 是一个实例变量 - 可用于类中的所有方法。

    【讨论】:

    • 嗨,合并您的帖子和提供的替代答案,我是否可以假设放置 @ 的决定是基于两个条件分支中的类型一致性?我将另一个答案解释为因为sessions#create 可能render new,而new 不需要实例变量,redirect_to user 应该在没有@ 的情况下效仿。与UsersController 相比,users#create 可能render 'new' 肯定会返回@user,因此我们也应该只返回redirect_to @user
    • 不完全是。您使用redirect_to @user 而不是redirect_to user,因为简单地说,@user 已定义而user 未定义(在users#create 中)。并且@user 是定义的,因为如果@user.save 失败(即返回false),您可能需要它的形式。
    • @MarekLipka 是不是更像我们使用@user 而不是user 因为@user.save 是必不可少的,而user.save 不会以同样的方式工作?而且@user 更强大,因为任何更改都会更新到最新版本,而本地变量user 可能对我们不起作用。
    • @user.saveuser.save 如果它们具有相同的值,则它们的工作方式相同,因此情况并非如此。唯一的区别是可见性,@user 可以在视图中访问,user 不是,故事结束。
    • @MarekLipka 那么你怎么知道一个方法是否应该允许它的变量在视图中是可访问的呢?一般是因为User是为了这个目的而直接创建的,而Session是为了支持User,不一定需要看的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    • 2014-02-14
    • 1970-01-01
    相关资源
    最近更新 更多