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

时间:2009-07-27 08:49:26

标签: ruby-on-rails ruby

快速示例:用户在表单中输入用户名,在将其存储到应用程序的数据库中之前,我需要创建该文本用户名,从而使其永久小写。

我将把这段代码放在哪里,以及如何访问要小写的数据?

感谢。

7 个答案:

答案 0 :(得分:77)

你应该覆盖属性writer:

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

答案 1 :(得分:49)

您可以在用户模型中使用ActiveRecords回调之一,例如:

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

答案 2 :(得分:14)

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

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

答案 3 :(得分:6)

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

我在这里提供了答案,因为此主题是完成此任务的第一个Google结果,但并未涵盖整个返回的false问题。

如果您的任何回调返回false,则所有内容都将在数据库中回滚。

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

我之后通过隐式返回true来修复它

有效的代码:

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

外卖:如果您希望它们成功,您的回调将无法返回false

来源:rails 3 : Do i need to give return true in a before_save callback for an object.save to work?

答案 4 :(得分:3)

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

我觉得这更容易。

答案 5 :(得分:0)

在一般情况下,表单上的“提交”按钮应委托给控制器操作 其中params [:user_name]可用。在做之前你可以小写 SomeModel.update(params)或create(params)。

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

答案 6 :(得分:0)

我建议在模型中添加Observer并在before_save方法中执行此操作。然后保证用户名小写,无论哪个控制器或操作正在创建它,如果在观察者中执行任何操作时出现问题,则抛出异常并且对象不会保存。

编辑:请注意,不能在与该模型关联的before_save中执行Model.save,否则最终会进入无限循环。你需要做一个update_attributes或者什么。