I’m a Rails newbie who need advice on strategy for routing and such for some Rails attributes…my very first hand-made attributes. What I have works, but I’m pretty sure there’s a better way to do it. A sample user show
page is viewable here. The repo is here.
I just finished Hartl’s Ruby on Rails Tutorial, which has a User
model with the usual name
, email
, and password
attributes. Then I figured I’d add a title
and a description
for the person. These seemed like User
attributes, but I didn’t want them to be edited on /users/<id>/edit
but instead on /users/<id>
, which is associated with get user_path(<id>)
. But I went ahead and did the following.
Relevant routes:
resources :users do member do post 'reactivate' # Resends the activation email. patch 'update_description' # Posts title & description. end end
First question: Should I put title
and description
in a new model, e.g., a Profile
model? (Then I guess the Profile
belongs_to
the User
?) If not, should I have separate paths and actions for updating title
and description
? If I don’t have a separate model, I guess I should have separate paths, but the reason I had only one path and action is that it seemed implausible that there would be a separate action for every data field on the site.
My controller action, Users#update_description
, is embarrassingly long and need refactoring, and it was actually when I sat down to refactor it that I decided to go back to the drawing board (and get help here):
# Handles user's posted title and description. def update_description @user = User.find(params[:id]) # For smart message, first check if user had a title. old_title = @user.title # For smart message, first check if user had a description. old_desc = @user.description if title_desc_params[:title] # And clear out any bad titles. session[:bad_title] = nil # Save title, if present. if title_desc_params[:title].present? # Attempt to save; if failed, flash with warning. begin @user.update_attributes!(title: title_desc_params[:title]) rescue ActiveRecord::RecordInvalid flash[:warning] = "Unable to save. (Too long?)" session[:bad_title] = title_desc_params[:title] end elsif old_title @user.update_attributes!(title: nil) flash[:info] = "Title deleted." end end # Same logic as before, now for description. if title_desc_params[:description] # And clear out any bad descriptions. session[:bad_desc] = nil # Save description, if present. if title_desc_params[:description].present? # Attempt to save; if failed, flash with warning. begin @user.update_attributes!(description: title_desc_params[:description]) rescue ActiveRecord::RecordInvalid flash[:warning] = "Unable to save. (Too long?)" session[:bad_desc] = title_desc_params[:description] end elsif old_desc @user.update_attributes!(description: nil) flash[:info] = "Description deleted." end end # Make sure two different [:success] flashes work! Probably not! redirect_to "/users/#{@user.id}" end
In the User
model, there are just these validations, nothing else:
validates :title, length: { maximum: 255 } validates :description, length: { maximum: 13_000 } # ~2000 words
If you want to see the view, that needs refactoring too…it’s here.
All advice very gratefully accepted, but the main thing I’m interested in is how to do the routing and controller actions for this. And was it OK/normal in Rails to put some field editing there on a show
page like that?