是否可以在不先阅读的情况下更改rails中的记录
Posted
技术标签:
【中文标题】是否可以在不先阅读的情况下更改rails中的记录【英文标题】:Is it possible to alter a record in rails, without first reading it 【发布时间】:2012-03-26 02:15:02 【问题描述】:我想更改一条记录,但我不想先从数据库中读取它,因为坦率地说我不明白这一点。它很大,而且通过一个缓慢而昂贵的网络。 可以(轻松)完成吗?
假设我有一条包含 100 个字段的记录(为了参数),我想更改表中的一个字段。我与数据库的连接非常糟糕(这是真的),因为它位于不同的盒子上,我无法改变它。 现在我拉下记录,rails 验证它的内容(因为我有序列化位)然后我更改一个字段(根据 X 条件的一百个字段之一)并再次保存记录。我想这会将整个记录再次写入数据库,而不知道我只更改了一点点。 (最后一点是假设)
现在要更改一条记录,它会通过网络发送大量数据,而我可能只更改了一件小事。 它还在数据库上执行两个查询。首先选择 * 然后更新..
所以我的问题.. 是否有更聪明的基类可以做到这一点,无需阅读即可编写? 在我的脑海中,我认为每个字段都有一个 setter 方法,并带有一个用于更改的 bool 标志。 保存时,走标志,哪里是真的......现在会发生这种情况吗,如果是,我该如何使用它?
【问题讨论】:
“(最后一点是假设)”——这是一个错误的假设。 ActiveRecord 足够聪明,只能写入更改的值。它内部已经有标记来跟踪哪些字段发生了变化。 实际上,查看文档(称为“部分更新”顺便说一句)它实际上只在边缘导轨中,直到 Rails 4 才发布。可能有一个“部分更新”插件或 gem . 是的,它是一个智能更新。关于首先进行查找,如果您知道要更新的内容,那么查找具有其 ID 的记录不是一个恒定时间操作吗?数据库可能有多大? @Shaunak 这不是我有问题的发现。它是从一个糟糕的服务器通过一个糟糕的网络读取程序内存。根本就是阅读记录,因为我不关心里面有什么。除了恒定之外,我认为它从来都不是我可以接受的。只有在我需要进行操作时才能进行恒定时间操作...否则我不妨在每行代码之后接受 sleep(100)。 【参考方案1】:Rails 模型具有 update
方法,该方法执行 SQL 选择,然后执行 SQL 更新。
它的使用很简单(假设你有一个名为 Person 的模型)
Person.update(person_id, :user_name => 'New Name')
缺点是你必须事先知道人名。
但是,您将始终需要进行查询才能找到答案。您可以编写自己的 SQL 来更改列值,使用 WHERE 子句搜索您拥有的参数。
Rails 模型具有 update_all
方法,该方法仅执行 SQL 更新而不加载数据。
但我不建议使用它,因为它不会触发您的模型可能具有的任何回调或验证。
您可以像这样使用 update_all:
Book.update_all "author = 'David'", "title LIKE '%Rails%'"
ps:示例均取自 Rails 官方文档。如果您搜索 update 或 update_all,您将很快找到这两种方法。
看看那里,这是了解rails可以做什么的好地方。
Rails API link
【讨论】:
我可以编写自己的 sql,但是为什么要使用 activerecord 啊?谢谢你..不知道如何创建一个包含在我的模型中的..我的视图和控制器不应该知道发生了什么,只是他们正在保存。 有时你必须自己写东西,当你遇到非常具体的问题时,相信我,呵呵。但是,如果您的网站不是很大,每分钟有数千次访问,那么从数据库中获取 id 就可以了,使用普通方法,只有在您真的有理由时才担心。听听 Knuth 的话:“过早的优化是万恶之源。” 感谢您的更新。我可能会尝试在我的所有领域中使用它。不过还不确定如何。 好报价.. 我不同意他的观点.. 我更喜欢考虑 1:10:100 规则。似乎它经过了比邪恶根源更多的测试。我喜欢先考虑优化,然后再编码。 我认为使用 Person.update(person_id, :user_name => 'New Name') 的执行方式与查找和保存方法完全相同,只是它将在内部完成。【参考方案2】:从文档中看不出来,但update_all
是这个问题的答案。
Book.where(id: 123).update_all(title: "War and Peace")
只产生一个查询:
UPDATE `books` SET `books`.`title` = "War and Peace" WHERE `books`.`id` = 123
这个问题被问到已经有一段时间了,但对于 Rails 4/5/6 来说是这样。
【讨论】:
喜欢它!all
部分在这里是不必要的:Book.where(id: 123).update(title: "War and Peace")
。我正在使用 Rails 5。
对于 Rails 6 上的任何人 - 使用 update_all
。 update
将触发 SELECT 查询以上是关于是否可以在不先阅读的情况下更改rails中的记录的主要内容,如果未能解决你的问题,请参考以下文章
在 PHP 中是不是可以在不先提取其内容的情况下检查 Zip 文件的内容?
如何在不先启动 IE 的情况下使我的 WinCE 应用程序中的网络工作?
如何在不先定义表中的列的情况下将数据加载到 PostgreSQL 中?
在不先显示 UIView 的情况下将 UIView 转换为 UIImage?