2012-04-13 62 views
13

我有一个徽标模型,其名称的字段为string:default:boolean。我希望真正的值是唯一的,以便数据库中只有一个项目可以一次设置为true。如何在我的控制器中设置我的更新和新操作以将我的徽标的所有其余值设置为false?Rails 3应用程序模型如何确保一次只有一个布尔字段设置为true

比方说,我有以下设置 在我的数据库
型号标志
名称:串|默认值:boolean |
商品1 | true |
商品2 | false |
商品3 | false |

如果我将Item2默认值更改为true,我希望它遍历所有徽标,并将其余部分设置为false,所以只有一个是同时存在的,所以它看起来像这样。

name:string |默认值:boolean |
商品1 | false |
商品2 | true |
商品3 | false |

感谢您提前提供任何帮助。

回答

18

此代码是从前面的答案被盗,稍作简化:

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

您可以在模型中使用的before_save回调此方法。

其实,这是更好地 “伪造” 只记录其值是 '真',是这样的:

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

UPDATE:保持代码干后,用self.class代替Item

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

+1使用回调。 – 2013-03-30 21:22:40

+3

更好地使用标准的sql为id比较''id <>?''。如果默认的当前值也是真的,那么确保你只关闭update_all。 – toxaq 2013-08-14 02:45:34

+0

超棒的男人!它非常完美! – 2013-11-17 13:47:23

3

在控制器代码,你可以做这样的事情....请注意你很可能会项目2作为设置了一个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 

享受!

+0

这很好,谢谢,现在我已经学会了将来如何做到这一点。 – ruevaughn 2012-04-13 05:31:20

+3

你最好在这里使用'update_all'。此代码可能正在执行数千个查询。 – Mischa 2012-05-27 07:24:02

3

我也建议伪造你的所有记录,然后使其成为真实。

add_column :users, :name ,:boolean, default: false 
3

好的还有一些你需要的东西。

请勿使用字段名称default,其通常为数据库保留。 将缺省记录保存为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 
+0

我遇到了这个。我一直在想,为什么我的falsify_all是在重写新的默认值。你说使用列名默认会导致类似的问题? – nathanengineer 2016-12-01 18:34:23

4

我认为在你篡改他人之前检查你保存的那个是否是真的很好。否则,当你保存一个不活跃的记录时,你就会伪造每个人。

def falsify_all_others 
    if self.default 
     self.class.where('id != ? and default', self.id).update_all("default = 'false'") 
    end 
end 
1

,如果你想这对于创建和更新工作(轨道V4) 请记下此珍闻从rails guides

after_save的同时运行的创建和更新,但总是愈后 具体回调after_create和after_update,无论其中执行宏调用的订单 。

相关问题