Rails字符串字段在模型中不保存

时间:2014-03-18 14:56:25

标签: ruby-on-rails

video = Video.find(79)
video.url.sub! "http", "https"
video.save

查看我的服务器控制台,当我发出此请求时,我看到了:

Video Load (48.7ms)  SELECT `videos`.* FROM `videos` WHERE `videos`.`id` = 79 LIMIT 1
(43.3ms)  BEGIN
(46.4ms)  COMMIT

注意,即使sub成功找到匹配项并进行替换,也不会进行UPDATE调用。

然而,做:

video.url = "https://example.com"
video.save

我明白了:

(40.6ms)  BEGIN
SQL (41.8ms)  UPDATE `videos` SET `url` = "https://example.com", `updated_at` = '2014-03-18 14:52:22' WHERE `videos`.`id` = 79
(57.8ms)  COMMIT

我一直在为此奋斗无数个小时。有谁知道发生了什么?

3 个答案:

答案 0 :(得分:4)

因为您使用sub!就地修改了字符串,所以Active Record为您生成的url=方法永远不会被调用,所以它不知道您已经修改过它。 / p>

您可以使用video.url = video.url.sub...方法,也可以将attribute_will_change!方法用于该特定属性:

video = Video.find(79)
video.url_will_change!
video.url.sub! "http", "https"
video.save

答案 1 :(得分:3)

有几种方法可以实现您的目标:

video = Video.find(79)
video.url = video.url.sub("http", "https")
video.save
# or
video = Video.find(79)
video.update_attributes(url: video.url.sub!("http", "https")) # does not need a save here

要测试并查看更新/保存之间对象的更改,您可以使用以下方法:

video = Video.find(79)
video.url.sub! "http", "https"
puts video.changes 
# will display changes as the following:
# { url: ['http://www.youtube.com/watch?v=npvNPORFXpc', 'https://www.youtube.com/watch?v=npvNPORFXpc'] }

Youtube视频:alt-J(Δ) - Fitzpleasure(官方音乐视频)

答案 2 :(得分:0)

可能与使用带感叹号的方法有关。大多数以!结尾的方法或多或少都有相同的问题,有时会返回nil

来自sub! docs

  

如果执行了替换,则返回str;如果没有替换,则返回nil   已经完成了。

然后,这可能不是你的问题。