Rails:向ActiveRecord模型添加方法

时间:2013-04-08 23:18:51

标签: ruby-on-rails ruby activerecord

我正在编写我的第一个相当简单的Ruby on Rails(3.2)应用程序。这个想法是管理电子邮件帐户。架构非常简单:

t.string   "email"
t.string   "password"

ActiveRecord模型定义为:

class Mailuser < ActiveRecord::Base
  attr_accessible :email, :password

我一直在使用脚手架,所有form_for(@mailuser)@mailuser.update_attributes(params[:mailuser])魔法。这很有效。

现在的怪癖是,应允许用户仅在时编辑电子邮件的用户部分(例如“foo”)(例如“示例”。 org“)必须保持不变。然而,电子邮件字段包含完整的电子邮件地址(例如“foo@example.org”)。因此,在编辑表单中,我不显示字段

  • 电子邮件
  • 密码

而是

  • userpart
  • 密码

userpart显示为@mailuser.userpart(可编辑)+ (不可编辑)。

所以我想我会通过为用户部分添加一个getter和setter来解决这个问题:

class Mailuser < ActiveRecord::Base
   attr_accessible :email, :password

   # Getter for the user part (left of '@')
   def userpart
      email.split('@')[0]
   end

   # Setter for the user part (left of '@')
   def userpart=(new_userpart)
      email = email.sub(/(.+)@/, new_userpart+"@")
   end

事实上,让@mailuser.userpart运作良好。它甚至可以在form_for(@mailuser)中正确显示。但是在控制器的@mailuser.update_attributes(params[:mailuser])方法中使用update保存表单时会出现问题。 Rails显然试图通过@mailuser从可用的属性更新attr_accessible对象。但userpart属性不反映实际的数据库字段。

所以我想知道将这些方法添加到ActiveRecord模型以添加功能的正确方法是什么?我已经习惯了Pylons(一个Python MVC框架),我可以一直使用这些额外的方法。

(实际上你想知道:我不能通过改变数据库模式来拆分用户和域部分。数据库被其他应用程序使用,所以我一直坚持它的外观。)

提前致谢。

2 个答案:

答案 0 :(得分:2)

您想要添加attr_accessible :userpart,以便可以通过update_attributes质量分配更新userpart。

已添加:如果您想要求Google先生提供更详细的解释,则userpart是虚拟属性的示例。

答案 1 :(得分:0)

解决方案的关键是虚拟属性。在我的例子中,实际的解决方案是:

  • 指定self.email而不是email来更改实例变量的值。仅使用email创建了一个局部变量。 (我不知道离开self只是Ruby的一个便利功能,可能会导致混乱,就像在这种情况下一样。)
  • 在模型中使用attr_accessible :userpart

在(非免费)http://railscasts.com/episodes/16-virtual-attributes-revised?autoplay=true截屏视频中对此进行了详细解释。我想知道在官方的Rails文档中解释虚拟属性的位置。