【问题标题】:Rails Controller ConfusionRails 控制器混乱
【发布时间】:2017-08-16 20:14:26
【问题描述】:

这是我的第一篇文章。

我是 Rails 的新手,我正在尝试学习如何使用它。需要明确的是,我对 Ruby 非常熟悉。我很确定我了解了 MVC 结构,但我无法理解我遇到的某些行为。

以防万一有人从同一来源了解到,我正在看 Derek Banas 解释它。他解释了我在 16:20 左右遇到的问题。 https://www.youtube.com/watch?v=GY7Ps8fqGdc

具体细节- 所以我将这一行放在了我的 routes.rb 文件中:

 match':controller(/:action(/:id))', :via => :get

我使用这个在控制器中创建了一个实例变量:

  def sample
    @controller_message = "Hello From The Controller"
  end

在我创建的示例视图中,我像这样调用“controller_message”变量:

<%= "#{@controller_message}" %>

它有一半的时间在那个视图上工作。现在根据我的理解,我应该在该代码行放置在视图中的任何位置看到“控制器的Hello”,对吗?也许我只是不明白这个功能是如何工作的,但我在同一目录中制作了其他视图文件,试图了解控制器如何将数据传递给视图。他们加载和一切,但我没有收到来自控制器的消息。有时,看起来不一致,控制器消息甚至不会显示在它最初工作的第一个视图上,特别是如果我稍微浏览一下站点。要让它再次显示该消息,我必须重新启动我的服务器。

我只是误解了 MVC 的工作原理,还是我的软件出现故障(我知道这不太可能),还是什么?我很混乱。

我听说过很多关于这个社区的好消息。提前感谢任何愿意帮助我的人。我太紧张了。

【问题讨论】:

  • 这是一个糟糕透顶的教程。创建诸如match ':controller(/:action(/:id))', :via =&gt; :get 之类的“神奇”路由可能看起来聪明,但会在您的应用程序中打开任何操作以获取请求!
  • 我理解你为什么会这样说,但我向你保证,他被认为是一名编程老师。我相信他使用“魔法”路由的原因是为了在他转向路由之前,他可以专注于解释控制器和视图之间的关系。 MVC 模型结构对新手来说有点令人生畏。我的意思是学习所有部分如何一起工作。
    但是,我喜欢从多个来源学习。所以如果你想为初学者推荐一个好的教程,我一定会看的。
  • M. Hartl 的 Rails 教程相当不错。他通过使用脚手架命令而不是这种废话来更好地解释 MVC。
  • M. Hartl 的 Rails 教程是 RoR 的圣经!大声笑
  • 谢谢,我去看看。作为记录,Derek Banas 确实在同一视频的后面使用脚手架进行了解释。

标签: ruby-on-rails model-view-controller controller


【解决方案1】:

&lt;%= "#{@controller_message}" %&gt;中的#{}是字符串插值。在视图中显示实例变量的通常约定是简单的&lt;%= @controller_message %&gt;

sample 方法中声明的变量@controller_message 使该变量可用于与该方法关联的视图。默认情况下,rails 会查找与控制器方法同名的对应视图文件,因此在这种情况下,它会在app/views/your_controllers_name 文件夹中查找名为sample.html.erb 的视图

【讨论】:

  • 非常感谢您提供非常明确的答案。我的意思是,哇!你解释得很好。我对你的评论投了赞成票,但它还不会显示,因为我的积分少于 15 分。
  • 没问题! :) 。我建议一开始不要使用太多的生成器/脚手架,一旦你知道引擎盖下发生了什么,它们就会派上用场,但在你这样做之前看起​​来就像“魔法”
【解决方案2】:

好吧,澄清一下(因为你的问题有点含糊):rails 在幕后做了很多事情,比如将控制器的名称与视图的名称相关联。这就是为什么在大多数情况下,您不会在控制器的方法中调用要呈现的视图(Rails 根据文件名对您执行此操作)。因此,控制器方法中声明的变量仅显示在与调用的控制器方法同名的视图中是有意义的。如果要在与控制器方法无关的视图中显示变量,则应使用 Render 和 Redirect 等方法调用该视图,并将变量作为参数传递给这些方法。

I.g:

其他控制器

def edit          
  render "/another_view_folder/example.html.erb", @variable_to_be_displayed
end

另一件事:

<%= @controller_message %>

这足以显示变量。您所做的方式是插值(用于将变量与字符串连接)。

希望能帮到你!

【讨论】:

  • 感谢您的帮助!这很有道理。
【解决方案3】:

如果在视图路径中找到视图文件,Rails 将隐式渲染它。

所以给定:

# config/routes.rb
get 'foos/bar'


# app/controllers/foo_controller.rb
class FoosController < ApplicationController
  def bar
    @controller_message = 'Hello'
  end
end

当我们请求/foos/bar 时,Rails 将尝试在app/views/foos 中查找文件bar.html.erb。如果我们想渲染另一个视图,我们需要告诉 rails render it explicitly.

class FoosController < ApplicationController
  def bar
    @controller_message = 'Hello'
    render 'some_other_view' # renders app/views/foos/some_other_view.html.erb
    # or
    render 'some_other_folder/some_other_view' # renders app/views/some_other_folder/some_other_view.html.erb
  end
end

现在根据我的理解,我应该在该行代码放置在视图中的任何位置看到“来自控制器的问候”,对吧?

没有。假设您添加了另一个控制器和视图。

# config/routes.rb
get 'people', to: 'people#index'

# app/controllers/people_controller.rb
class PeopleController < ApplicationController
  def index
  end
end

# app/views/people/index.html.erb
<h1>The message is: <%= @controller_message %></h1>

它只会渲染The message is:。由于PeopleController 没有设置实例变量@controller_message。如果您引用未分配的实例变量,Ruby 不会引发错误。

推理的方法是 Rails 中的控制器将其所有实例变量打包并将它们传递给视图上下文,以便我们可以在视图中使用它们。

控制器完成渲染后,它发送渲染的模板,程序退出*。实例变量、局部变量等不会延续到下一个请求。

【讨论】:

  • 至于不一致 - 它并不是真正的预期行为,但我猜它更多地归因于用户错误而不是框架中的实际错误。
猜你喜欢
  • 2018-04-13
  • 2016-06-30
  • 2012-04-02
  • 1970-01-01
  • 2012-11-26
  • 2020-08-22
  • 1970-01-01
  • 1970-01-01
  • 2010-11-30
相关资源
最近更新 更多