【问题标题】:How to check if attribute is changing in update action in Rails?如何检查 Rails 中更新操作中的属性是否发生变化?
【发布时间】:2012-10-04 14:14:39
【问题描述】:

我正在尝试检查 - 某些(语言)属性是否已更改,如果它等于某个值,我需要将其更改为其他适当的值。

这是我的代码:

编辑

    def update
@website = Website.find(params[:id])
@website.language = params[:website][:language]
if @website.language_changed?
  if params[:website][:language] == "Automatic (by user's browser language)"
    @website.language = full_language(request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first)
  end
end
respond_to do |format|
 if @website.save
   format.html { redirect_to @website, 
  notice: 'Note: code has been updated. Please replace the code you have on your website with the code below. Only then changes will take effect.' }
   end
  end
end

我的表格:

  <%= f.label "Website category"%>
  <%= f.select :category, options_for_select([
      "--- please select ---",
      "Banking",
      "Computers]) %>
  <%= f.label "Language preferences"%>
  <%= f.select :language, options_for_select([
       "--- please select ---",  
       "Automatic (by user's browser language)",
        "Arabic",
        "Chinese"]) %>

当我更改类别时 - 它会将语言更改为默认值。我怎样才能防止这种情况发生?

给我错误:

   undefined method `updated?' for "--- please select ---":String

我做错了什么?

【问题讨论】:

  • 尝试@website.changes - 返回哈希,左边是对象中的内容,右边 - 将会是什么。

标签: ruby-on-rails actioncontroller


【解决方案1】:

我刚刚通过控制台进行了尝试,当您执行像 @website.attributes = params[:website] 这样的大规模属性更新时,ActiveRecord 似乎没有跟踪更改。像if @website.language != params[:website][:language] 这样的事情可能更简单(当然,稍后将您的更新移动到某个地方。)。有点丑,我意识到,但它会工作。当然,您始终可以考虑增强您的模型以跟踪大规模更新带来的变化。

关于更改的字段 - 听起来您的选择列表未初始化为正确的值。如果@website.category 的值为“foo”,那么当此页面加载时,选择列表应该选择“foo”。这似乎没有发生,所以当您提交表单并进行质量属性更新时,它会将类别属性更新为默认选择的任何列表项。

【讨论】:

  • 谢谢,@Scott 如何使用正确的值初始化 selectBox?
  • 如何分别更改类别和语言?
  • 当您执行form_for 时,您应该能够指定form_for @website,其中@website 是在此视图的操作中初始化的对象。如果您正在做这些事情,我认为助手会为您初始化选择列表。如果没有,请检查文档中的 rails select helper - 您应该能够传入当前选择的值以强制它初始化为该值。
  • 你的意思是,让第一个选项 = @website.category ?
  • 实际上,我刚刚注意到您在调用选择助手的位置有"Computers]) - “计算机”值没有结束引号。这只是您帖子中的错字吗?
【解决方案2】:

@website.language_changed?是方法,可以看http://railscasts.com/episodes/109-tracking-attribute-changes

def update
  @website = Website.find(params[:id])

  if params[:website][:language] == "Automatic (by user's browser language)" &&  @website.language != params[:website][:language]
    params[:website][:language] = full_language(request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first)
  end
  if @website.update_attributes(params[:website])
  end

end

【讨论】:

  • 好的,谢谢。但是当我在一个选择列表中更改值时,另一个字段正在更改。
  • 其他字段有变化吗?我不明白你可能只想设置语言字段@website.language=params[:website][:language]
  • 我的意思是当我更改类别时 - 语言正在更改为默认值,当我更改语言时 - 类别也在更改。
  • 我想让它保持不变,直到用户更改它。
  • 所以你不想在更改语言的同时更改类别,如果这是你的情况,那么@website.attributes = params[:website] 使用@website.language=params[:website][:language]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-05
  • 2012-08-01
  • 2023-04-01
  • 2011-06-30
  • 1970-01-01
  • 2021-04-08
  • 1970-01-01
相关资源
最近更新 更多