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什么的。