views:

42

answers:

3

I have a User model with the usual information (login, email, name, location, etc). However, when users decide to edit their information, I'd like to separate the fields to be edited according to the appropriate concerns.

For example, I'd like to have Name, Bio and Location to be edited on a Profile page or tab, and login, email and password to be edited on an Account page or tab.

What are the best practices, and the safest way, to accomplish that? Should I have two separate model/resources: User and UserProfile? Or can I just create something like a profile method in the UserController, with a custom form with only the specific profile fields, and link to it in the user page? I'm really confused on how to go about this.

Thanks in advance for any ideas you might have.

+1  A: 

I would be inclined to cut along the grain here. It's going to be easier to map a model to a form. So if you have information that is accessed within different forms in your UI, I would create a model for each.

That said, at a certain point in my systems I tend to pull the profile information out of the base User class, so the User becomes solely for authentication.

Toby Hede
+1  A: 

I think it depends on the rest of your Application. It sounds like in your case it's good to be modular. If you want users to be able to see the profile of other users, it's an advantage to have a separate model for the Profile and like it with a has_one relationship. I'd just call the class Profile so it can be accessed through user.profile in your controllers and views.

Models:

class User < ActiveRecord::Base
  has_one :profile, :dependent => :destroy
end

class Profile < ActiveRecord::Base
  belongs_to :user
end
ghoppe
Thanks. I'm going to be trying out yours and klew's approach, and should accept the one that I feel works best for me soon.
Baby Diego
+1  A: 

If all your users have both profile and account fields then I wouldn't put it in seperate models. It will only add unnecesary complexiety to your forms and add may add some sql queries.

I don't see here any security problems. In case of editing, both actions (edit account and profile) should be protected the same way - so only owner user should be able to edit both of them. If he want to "hack" it and edit also his login when he edits his first name then it is his problem. It won't cause any problem since he is allowed to edit both fields.

According to views that are viewable for other people: just don't display there any fields that belongs to account part.

How to seperate it? For me the cleanest way is to add this kind of routes:

map.resources :accounts
map.resources :profiles

And use paths like /accounts/34/edit to edit account part and /profiles/34/edit to edit profile part.

In this case you will need a seperate controller for both routes: accounts_controller.rb and profiles_controller.rb. If they share a lot of similar methods and behavior, you can add it in users_controller.rb and in profiles and accounts controllers inherit from it.

You can also do it with one controller:

map.resources :accounts, :controller => 'users'
map.resources :profiles, :controller => 'users'

But I don't know how to pass some additional value with routes created with resources. When you use connect you can pass it with :defaults => {:foo => 'bar'} and then it will be availble in controller as params[:foo] but it doesn't seem to work with resources. So how can you distinguish between accounts and profiles? You can read it from current url (here is example). And then in controller you can render different views according to requested resource.

klew
I'm not a Rails expert by any means, but I don't understand why it may add some sql queries. If there are some views that only display profile information wouldn't it potentially reduce queries?
ghoppe
@ghoppe: when he has one model, then for sure it will be queried only once. When he has two tables and he loads `@user = User.find(params[:id])` and then he uses `@user.profile.login` then it will make a second query. I'm not sql expert but I think it is better to have one table with more columns than two tables with fewer columns if for sure we will use both of them and join them.
klew
Thank you for the thorough answer. I'm going to be trying out yours and ghoppe's approach, and should accept the one that I feel works best for me soon.
Baby Diego