【问题标题】:overriding a value to true and setting the rest to false in rails在rails中将一个值覆盖为true并将其余的设置为false
【发布时间】:2009-11-11 04:49:05
【问题描述】:

这是一个非常愚蠢的问题,但我有一个截止日期,我很紧张,我已经尝试了所有方法。事实上,它甚至可以工作一秒钟,但我一定是弄坏了一些东西。

我有一个默认的特色项目,我想在任何时候尝试以另一个项目为特色时覆盖它。我之前让它出错,但我不希望它出错,我只是希望它将所有内容设置为 false 并将此应用程序设置为 true。

我已经尝试了一切,在保存之前,在保存/更新命名范围之后,将每个映射到 false,然后保存,检查功能是否已更改...我认为我拥有所有正确的部分,但我可以'不要把它们放在一起。请帮忙:(

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

我无法用代码详细说明,因为我已经尝试了上百万种不同的东西。

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

创建项目时,您可以将其设置为特色或不特色。

在数据库中,如果其他项目有特色,这些项目应该归零,并且刚刚更新或创建的项目应该是真实的。

我已经在模型中使用之前/之后/保存/更新以及创建和更新控制器进行了尝试

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

在控制器中:

  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}

结束

  named_scope :is_on_front_page, :conditions => { :is_on_front_page => true }
    after_update do
    if self.is_on_front_page.changed? and App.is_on_front_page.count >= 1
     App.all.map{|m| m.is_on_front_page = false;m.save}

    end 
    is_on_front_page = true
    save!
   end

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

【问题讨论】:

  • 您需要提供一些详细信息。例如,商品的特色如何?
  • 您能详细说明一下代码吗?

标签: ruby-on-rails ruby validation


【解决方案1】:

在事务中,只需将 all 设置为 false,然后将您想要的记录更新为 true(精选)。这类似于有时更容易删除记录然后找到它们并更新它们。也就是说,这样做更容易:

交易做 SomeModel.delete_all 项目.每个 { |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

【讨论】:

  • 这就是我想要做的!!!但是没有用!!看我的代码。我需要检查它在保存之后或之前是否发生了变化,然后只需清除所有内容并将当前项目设置为 true。我不知道为什么它不起作用
  • @stacia - 查看我的更新条目。基本上只需使用一个清除所有其他记录的回调,然后将新创建的记录设置为特色。
  • 为什么这不起作用???如果@app.is_on_front_page_changed? == true App.is_on_front_page.map{|m| m.is_on_front_page = false} 结束
  • 非常感谢。我得到它的工作: def set_as_featured self.class.transaction do App.update_all(:is_on_front_page => false) self.update_attribute(:is_on_front_page, true) end end 但是更新后我仍然得到一个无限循环......什么我该怎么做?
  • 你得到了一个无限循环,因为每个 after_update 回调都在自己输入。在您的 after_update 方法中,您更新触发另一个回调的模型。您有两个选择,这实际上取决于您的产品:1) 使用 after_create 而不是 after_update(具有明显的局限性)或 2) 直接访问数据库而不是使用 update_attribute。像 self.connection.execute("UPDATE foo SET features=0") self.connection.execute("UPDATE foo SET features=1 WHERE id = #{self.id)") 这不会触发任何 ActiveRecord 回调,因为它侧面-步骤 AR。
【解决方案2】:
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

这是你需要的吗?要挑选特色商品?

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

如果未提供某些内容,您可以在 before_create 或 before_update 挂钩中设置默认值,但除此之外,我需要一些关于您的具体细节的指导。

【讨论】:

  • 假设我有 10 件商品,我只想展示其中一件。也许第 2 项已经出现。当我去创建一个新项目时,我希望将所有项目(实际上只是项目 2,但现在有不止一个特色,所以我们将保留它)设置为 FALSE 并且我创建的项目/刚刚更改/更新为设置为真。这有意义吗?
  • 查看其他答案。我认为这更符合你的要求。不过,我要把它留给后代。
【解决方案3】:

好的,我要添加一个单独的答案,因为我想我明白你在说什么。

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

如果您有商店 has_many :items,您可以在商店中放置“featured_item_id”的属性并存储 features_id。如果需要设置默认值,请添加“default_item_id”并将默认值放在那里。

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

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

...确保始终有一个默认值,这样您就不会遇到 nil item 问题。

【讨论】:

  • 我想这会起作用,但它似乎有点矫枉过正。我只处理布尔值。它要么有特色,要么没有。我只想要一个 00000 的列表,然后是一个 1 的精选列表。只需将所有内容归零,然后在我更新的地方放置一个 true 或一个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多