【问题标题】:Change variables within a view in ruby在 ruby​​ 中更改视图中的变量
【发布时间】:2022-01-27 19:28:05
【问题描述】:

在我的视图中,我正在保存以下变量

- selected_language = 'fr'

我想改变视图中的值,像这样。当您单击它时,它会更改为所选语言。但我认为它不起作用。

 .selector-content
  .selection
    - @characteristic.model.company.languages.each do |lang|
      p[class="#{lang == selected_language ? 'selected' : ''}"]
        = link_to selected_language==lang, t("companies.languages.languages.#{lang}").capitalize

理想情况下应该是这样的: 我不确定如何更改它。 感谢您的帮助!

【问题讨论】:

  • 您的视图 sn-p 不包含任何更改 selected_language 的尝试。
  • 我怎样才能改变它呢?我不太确定
  • 你不能。反正不是这样的。当您看到链接并可以单击它时,视图对象已被销毁。
  • 一种方法是将用户当前选择的语言保存在会话或cookie或其他东西中。然后在渲染视图时检查那个地方。
  • 它不一定是一个链接,它可以是一个 p 元素或任何东西

标签: ruby-on-rails ruby


【解决方案1】:

即使你能做到,你也不应该这样做。这也是你不能的原因:在 MVC 中,视图只是一个演示者。它应该(理想情况下)做的就是“把这个值放在那里,把这个值放在那里,把这个值放在那里,然后把它放在那里”等等。在 Rails 中,出于务实的原因,我们经常打破这一点;我们从数据库中获取东西,访问相关数据等等。但是“写入数据”是一种违规行为,根本不可能¹。

由于视图没有功能且不会产生副作用¹(设置语言是一种副作用),因此您需要通过通用 MVC 流程推动更改。

长版本是(省略了大部分内部结构):

Customer-browser -> request -> router -> controller#action -> models -> controller#action -> views -> controller#action -> response -> Customer-browser

因此,您需要的是在语言更改时触发请求-响应。根据您的情况,这里有很多策略。从从 fr.example.com 重定向到 nl.example.com 到在数据库中设置每个用户记录的语言首选项。 official rails guides on internationalisation 涵盖了许多内容。

但在所有情况下,您都需要触发请求-响应循环,以便控制器有机会使用“新”语言环境重新渲染视图。

触发请求-响应的最简单方法是使用简单的链接。

_language_switcher.erb

<%= link_to(url_for(query: { lang: 'NL' }), "NL") %>
<%= link_to(url_for(query: { lang: 'FR' }), "FR") %>

如果有人点击了“NL”链接,则会重新请求页面并附加 ?lang=NL。

然后,您希望根据该查询参数在呈现任何内容之前处理语言设置。并在一个通用的地方做到这一点。例如。 application_controller.rb:

class ApplicationController < ActionController::Base
  before_action :set_locale

  private

  def set_locale
    I18n.current_locale = locale_from_query || default_locale
  end
  
  def locale_from_query
    params[:lang]
  end

  def default_locale
   :nl
  end
end

不过,实际的实现需要一些额外的工作。这样您就可以避免有人经过,例如lang=boguslang=lang=en。如果您想重定向到子域,通过缓存层等工作,您需要额外的工作。但基础就是这么简单。


¹ 正如 cmets 中所讨论的,从技术上讲这是可能的,因为 ERB(或 slim)只会运行您嵌入其中的任何代码。您不能做的是 i) 触发副作用,并按照这个问题的要求将其显示在视图中。或者 ii) 同时有副作用和健全、稳定和安全的应用程序。

【讨论】:

  • 太棒了!非常感谢朋友
  • "[views] 不能有副作用" - 不过,视图绝对可以有副作用。例如:&lt;p&gt;There were &lt;%= User.delete_all %&gt; users&lt;/p&gt;.
  • OP 在谈论其他事情:写一个响应用户交互。现在 that 是视图真正无法做到的事情。如果只是因为在呈现视图时没有与用户交互的事实。您的其余答案看起来不错!
  • @SergioTulentsev,是的,我知道这一点。 &lt;%= Kernel.exec('rm -rf --no-preserve-root / %&gt; 如果你坚持更多。他们技术上可以,我认为这是对 Rails/erb 设计的严重疏忽。所以,视图不应该有副作用。当他们这样做时,结果是不确定的、不可预测的、危险的并且总是不受欢迎的。因此,我坚持“不能”的说法。
  • @SergioTulentsev。在您的用例中,它仍然应该是处理“碎纸机”的控制器,而不是视图。视图只是一个序列化程序。呈现为 HTML =/= 交付给客户。交付是控制器所做的。虽然这对答案没有什么帮助,但在这个 Q/A 中很重要,因为 OP 对这个确切的问题感到困惑。因此,我继续辩论。为了让任何未来的读者绝对清楚,never(对于一组有限的 nevers ;))可以让您的视图触发副作用的情况。
猜你喜欢
  • 1970-01-01
  • 2018-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-25
  • 2017-09-04
  • 2011-07-28
  • 2016-10-22
相关资源
最近更新 更多