Ruby on rails 在rails中将值重写为true并将其余值设置为false

Ruby on rails 在rails中将值重写为true并将其余值设置为false,ruby-on-rails,ruby,validation,Ruby On Rails,Ruby,Validation,这是一个非常愚蠢的问题,但我有一个最后期限,我非常紧张,我已经尝试了一切。事实上,它甚至工作了一秒钟,但我一定打破了什么 我有一个默认的特色项目,我想在任何时候我试图特色另一个项目被覆盖。我让它给一个错误之前,但我不希望它出错,我只希望它设置一切为假,这个应用程序为真 我尝试了一切,在保存之前,在保存/更新命名作用域之后,将每个作用域映射为false,然后保存,检查功能是否已更改…我认为我拥有所有正确的部分,但我无法将它们组合在一起。请帮忙:( 也许有一个快速的验证,我不确定 我无法用代码来详细

这是一个非常愚蠢的问题,但我有一个最后期限,我非常紧张,我已经尝试了一切。事实上,它甚至工作了一秒钟,但我一定打破了什么

我有一个默认的特色项目,我想在任何时候我试图特色另一个项目被覆盖。我让它给一个错误之前,但我不希望它出错,我只希望它设置一切为假,这个应用程序为真

我尝试了一切,在保存之前,在保存/更新命名作用域之后,将每个作用域映射为false,然后保存,检查功能是否已更改…我认为我拥有所有正确的部分,但我无法将它们组合在一起。请帮忙:(

也许有一个快速的验证,我不确定

我无法用代码来详细说明,因为我已经尝试了一百万种不同的方法

在一个名为is_featured的项目上有一个布尔设置

创建项目时,可以将其设置为“特色”或“非特色”

在数据库中,如果其他项目具有特色,则应将其归零,并且刚刚更新或创建为特色的项目应为true

我在模型中使用before/after/save/update以及create和update上的controller尝试了这一点

好吧,我会添加一些我不知道为什么不起作用的愚蠢代码

在控制器中:

  if params[:app][:is_on_front_page] == true
App.all.map{|m|( m != @app ) ? m.is_on_front_page = true : m.is_on_front_page = false}
结束

但它不会让我保存或进入无限循环,也不会因为命名范围而对我大喊大叫

if params[:id]  # or however you're setting the overridden featured item
  @feature = Feature.find(params[:id])
else
  @feature = Feature.default  # make a self.default method that returns the default
end
这就是你需要的吗?挑选特色商品

我不确定你到底需要什么。验证是为了保存一些东西,所以我不确定那里会有什么“特色”。一个澄清的评论会有所帮助


“创建前”或“更新前”钩子是在没有提供某些内容的情况下设置默认值的钩子,但除此之外,我需要一些关于您的具体说明的指导。

好的,我添加一个单独的答案,因为我想我明白您的意思

您有一个项目列表,希望其中一个项目具有特色。有人可以选择其中一个项目作为特色项目,但如果没有,则默认情况下会有一个后备项目具有特色

如果您的商店有多个:项目,您可以在商店上放置“特色项目”的属性并存储特色项目。如果需要设置默认值,请添加“默认项目”并将默认项目放在其中

在商店中为他们添加关系:

belongs_to :featured_item, :class => Item, :foreign_key => 'featured_item_id'
belongs_to :default_item,  :class => Item, :foreign_key => 'default_item_id'
然后,创建一个测试并返回正确方法的方法:

def featured
  if self.featured_item_id
    self.featured_item
  else
    self.default_item
  end
end
如果您将一个项目设置为特色项目,您将获得该项目。如果未设置,您将获得默认项目。您可能还需要:

validates_presence_of :default_item_id

…以确保始终存在默认值,从而不会出现零项问题。

在事务中,只需将all设置为false,然后更新要为true的记录(特色)。这类似于有时删除记录然后查找并更新记录更容易。也就是说,执行以下操作更容易:

交通部 SomeModel.delete\u all items.each{i|SomeModel.create(i)} 结束

这比在SomeModel上循环执行find()然后更新某些属性更容易

在您的情况下,您只需要将所有记录标记为“未精选”,然后将您想要的记录更新为“精选”,而不是手动切换记录

试着这样做:

after_create :set_as_featured

def set_as_featured
 self.class.transaction do
   self.connection.execute("UPDATE foo SET featured=0")
   self.update_attribute(:featured, true)
 end
end

你需要提供一些细节。例如,项目是如何特色化的?你能用一些代码来详细说明吗?假设我有10个项目,但我只想特色化一个。可能项目2已经特色化了。当我去创建一个新项目时,我想要所有项目(实际上只是项目2,但目前有不止一个特色化项目,所以我们将保持不变)设置为FALSE,而我创建/刚刚更改/更新的项目设置为true。这有意义吗?请参阅其他答案。我认为这更符合你的要求。不过,我将把这个留给子孙后代。我想这会起作用,但似乎有些过分。我只处理布尔人。它要么是特色的,要么不是。我只想要一个00000和t的列表当一个1出现时。只需将所有内容归零,然后将一个“真”或“一”放在我更新此内容的位置。这就是我试图做的!!!但它不起作用!!查看我的代码。我需要检查它在保存或其他任何操作后是否已更改,然后清除所有内容并将curernt项设置为“真”。我不知道为什么它不起作用work@stacia -查看我的更新条目。基本上只需使用回调清除所有其他内容,然后将新创建的记录设置为特色记录。为什么不起作用???如果@app.is_on_front_page_changed?==true app.is_on_front_page.map{m|m.is_on_front_page=false}End非常感谢。我使用这个:def set_as_featured self.class.transaction do App.update_all(:is_on_front_page=>false)self.update_属性(:is_on_front_page,true)end end然而我在更新后仍然会得到一个无限循环…我该怎么办?你会得到一个无限循环,因为每个更新后的回调都会反馈到自身中。在更新后的方法中,你会更新触发另一个回调的模型。你有两个选择,这实际上取决于你的产品:1)与使用update属性相比,使用after\u create代替after\u update(具有明显的限制)或2)直接命中数据库。与self.connection.execute(“UPDATE foo SET characterized=0”)self.connection.execute(“UPDATE foo SET characterized=1,其中id=#{self.id)”)类似,这不会触发任何ActiveRecord回调,因为它会跳过AR。
after_create :set_as_featured

def set_as_featured
 self.class.transaction do
   self.connection.execute("UPDATE foo SET featured=0")
   self.update_attribute(:featured, true)
 end
end