I'm writing my first rather simple Ruby on Rails (3.2) application. The idea is to manage email accounts. The schema is rather simple:
t.string "email"
t.string "password"
The ActiveRecord model is defined as:
class Mailuser < ActiveRecord::Base
attr_accessible :email, :password
I've been using scaffolding with all the form_for(@mailuser)
and @mailuser.update_attributes(params[:mailuser])
magic. That works well.
Now the quirk is that the user should be allowed to only edit the user part (e.g. "foo") of an email while the domain (e.g. "example.org") must stay untouched. The email field however contains the complete email address (e.g. "foo@example.org"). So in the edit form I don't display the fields
- password
but rather
- userpart
- password
where the userpart
is shown as @mailuser.userpart
(editable) + domain (not editable).
So I thought I'd solve that by adding a getter and setter for the user part like this:
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
In fact getting the @mailuser.userpart
works well. And it's even displayed properly in the form_for(@mailuser)
. But a problem occurs when saving the form using @mailuser.update_attributes(params[:mailuser])
in the controller's update
method. Rails apparently tries to update the @mailuser
object from the attributes made available through attr_accessible
. But the userpart
attribute does not reflect an actual database field.
So I wonder what is the proper way to add such methods to ActiveRecord models to add functionality? I'm used to Pylons (a Python MVC framework) and I could use such additional methods all the way.
(In fact you wonder: I can't split the user and domain parts by changing the database schema. The database is used by other applications so I'm stuck with the way it looks.)
Thanks in advance.
<%= f.text_field :userpart %>@<%= @mailuser.domain.name %>
<%= f.password_field :password %>