Rails: a "new or edited" path helper?

Is there a simple and easy way to provide a link in a view, to create a resource if it does not exist or to modify an existing one if there is one?

IE:

User has_one :profile 

Currently, I will do something like ...

 -if current_user.profile? = link_to 'Edit Profile', edit_profile_path(current_user.profile) -else = link_to 'Create Profile', new_profile_path 

This is fine if this is the only way, but I tried to see if there is a β€œRails Way” way to do something like:

 = link_to 'Manage Profile', new_or_edit_path(current_user.profile) 

Is there a good clean way to do something like this? Something like the equivalent of the view Model.find_or_create_by_attribute(....)

+8
new-operator ruby-on-rails ruby-on-rails-3 edit link-to
source share
5 answers

Write a helper to encapsulate a more complex part of the logic, then your views may be clean.

 # profile_helper.rb module ProfileHelper def new_or_edit_profile_path(profile) profile ? edit_profile_path(profile) : new_profile_path(profile) end end 

Now in your views:

 link_to 'Manage Profile', new_or_edit_profile_path(current_user.profile) 
+25
source share

I ran into the same problem, but I had many models for which I wanted to do this. It seemed tiring to write a new helper for everyone, so I came up with this:

 def new_or_edit_path(model_type) if @parent.send(model_type) send("edit_#{model_type.to_s}_path", @parent.send(model_type)) else send("new_#{model_type.to_s}_path", :parent_id => @parent.id) end end 

Then you can simply call new_or_edit_path :child for any child of the parent model.

+7
source share

Another way!

  <%= link_to_if(current_user.profile?, "Edit Profile",edit_profile_path(current_user.profile)) do link_to('Create Profile', new_profile_path) end %> 
+5
source share

If you want to use the general method:

 def new_or_edit_path(model) model.new_record? ? send("new_#{model.model_name.singular}_path", model) : send("edit_#{model.model_name.singular}_path", model) end 

Where model is your instance variable on your view. Example:

 # new.html.erb from users <%= link_to new_or_edit_path(@user) do %>Clear Form<% end %> 
+1
source share

Try the following:

 module ProfilesHelper def new_or_edit_profile_path(profile) profile ? edit_profile_path(profile) : new_profile_path(profile) end end 

and with your link:

 <%= link_to 'Manage Profile', new_or_edit_profile_path(@user.profile) %> 
-4
source share

All Articles