Ruby on Rails – 我可以在保存之前修改数据吗?

快速示例:用户将一个用户名input到表单中,并且在将该用户名存储到应用程序的数据库中之前,需要先创build该用户名,从而使其永久为小写。

我会在哪里放这个代码,我将如何访问数据被小型化?

谢谢。

你应该覆盖属性编写器:

class User < ActiveRecord::Base def username=(val) write_attribute(:username, val.downcase) end end 

你可以在你的用户模型中使用ActiveRecordscallback之一,例如:

 before_save { |user| user.username = user.username.downcase } 

在您的用户模型(models / user.rb)中,利用ActiveRecordcallback:

 before_save do self.username = self.username.downcase end 

我花了一段时间查找一个阻止我使用此代码的bug。 每次我试图拦截一个属性时,我的数据库都会回滚,并在保存之前将其更改为false

我在这里贡献我的答案,因为这个线程是Google完成这个任务的第一个结果,但没有涵盖整个返回的false问题。

如果你的callback函数返回false那么所有的callback函数都会回滚到db中。

我试图设置一个要创build的要约不被接受的数据库或@offer.accepted = false 。 问题是这一行导致整个方法返回false并回滚整个过程。

之后,我通过一个隐含的回报来固定它

代码工作:

before_save {|offer| offer.accepted = false; true}

外卖:如果你想让他们成功的话,你的callback不能返回false

来源: 导轨3:我需要在before_savecallback中返回真正的object.save工作?

 def username=(str) super(str.downcase) end 

我觉得这更容易。

在一般情况下,表单上的提交button应委派给一个控制器操作,其中params [:user_name]可用。 在做一个SomeModel.update(params)或者创build(params)之前,你可以小写。

所以你可以在控制器操作中做到这一点。

我会build议在模型中添加一个Observer ,并在before_save方法中执行这个操作。 那么无论哪个控制器或动作创build它,都保证小写用户名,并且如果在观察者内部执行任何动作时出现问题,则抛出exception并且该对象不会保存。

编辑:请注意,您不能在与该模型绑定的before_save中执行Model.save,否则您将以无限循环结束。 你需要做一个update_attributes什么的。