16

name:string、default:boolean のフィールドを持つ Logo モデルがあります。データベース内の 1 つの項目のみを一度に true に設定できるように、true の値を一意にする必要があります。コントローラーで update および new アクションを設定して、ロゴの残りのすべての値を false に設定するにはどうすればよいですか?

データベースに次の設定があるとしましょう
Model Logo
name:string | デフォルト:ブール値 |
アイテム1 | 真 |
アイテム2 | 偽 |
アイテム3 | 偽 |

Item2 のデフォルト値を true に変更すると、すべてのロゴをループして残りを false に設定したいので、一度に 1 つだけ true になるようにすると、このようになります。

名前:文字列 | デフォルト:ブール値 |
アイテム1 | 偽 |
アイテム2 | 真 |
アイテム3 | 偽 |

事前に助けてくれてありがとう。

4

9 に答える 9

22

このコードは前の回答から盗まれ、わずかに簡略化されています。

def falsify_all_others
  Item.where('id != ?', self.id).update_all("default = 'false'")
end

このメソッドは、モデルのbefore_saveコールバックで使用できます。

実際には、次のように、値が「true」であるレコードのみを「偽造」することをお勧めします。

Item.where('id != ? and default', self.id).update_all("default = 'false'")

更新:コードをDRYに保つには、次self.classの代わりに使用しますItem

self.class.where('id != ? and default', self.id).update_all("default = 'false'")
于 2012-04-13T05:46:33.480 に答える
5

他人を改ざんする前に、保存したものが本当かどうかを確認するのが良いと思います。そうしないと、アクティブでないレコードを保存すると、全員が改ざんされます。

def falsify_all_others
    if self.default
        self.class.where('id != ? and default', self.id).update_all("default = 'false'")
    end
end
于 2015-02-02T18:05:42.473 に答える
3

コントローラコードでは、次のようなことができます。おそらくItem2をparam [...]として使用しているので、以下でそれを交換できることに注意してください。

@items_to_be_falsified = Item.where('id != ?', Item2.id)

@items_to_be_falsified.each do |item|
  item.default = false
  item.save
end

Item2.falsify_all_othersこれを機能させるときは、これをモデルに移動し、関数にして、次のように呼び出すことをお勧めします。

def falsify_all_others
  Item.where('id != ?', self.id).each do |item|
    item.default = false
    item.save
  end
end

楽しみ!

于 2012-04-13T03:40:08.787 に答える
3

また、すべての記録を偽造してから、真実にすることをお勧めします。

add_column :users, :name ,:boolean, default: false
于 2012-08-03T08:14:00.820 に答える
3

さて、あといくつか必要なものがあります。

デフォルトのフィールド名は使用しないでください。通常はデータベース用に予約されています。デフォルトを false としてレコードを保存すると、すべてのレコードが false に設定されますが、これは望ましくありません。このレコードを true に設定しており、falseify を設定しているかどうかを確認してください。

  before_save :falsify_all_others
  def falsify_all_others
    if is_default
      self.class.where('id != ?', self.id).where('is_default').update_all(:is_default => false)
    end
  end
于 2014-08-29T15:21:49.903 に答える
1

より多くの ActiveRecord、より少ない生の SQL 決定

after_commit :reset_default, if: :default?

private

def reset_default
  self.class.where.not(id: id).where(default: true).update_all(default: false)
end
于 2022-01-24T12:00:48.863 に答える