Reputation: 4728
I am using devise and has created a model profile.
I have added the has_one relationship to user and belongs_to :user to profile model. I have also added user_id column in profile.
I have also added
before_filter :create_profile
def create_profile
profile = Profile.create
end
in User model. When a new user registers it a new profile do gets created. So if the user id is 10, this is what is getting created in profile
#<Profile id: 2, name: nil, created_at: "2013-08-17 06:44:33", updated_at: "2013-08-17 06:47:00", user_id: 10>
Now the problem is, I have put an edit link in application.rb
<li><%= link_to "Profile".html_safe, edit_profile_path(current_user) %></li>
but it is giving error
Couldn't find Profile with id=10
so instead of searching for id=2, it is looking at user_id, how to fix this ? I am sure I am missing out on something very small but not sure what.
EDIT - the error is coming from this line @profile = Profile.find(params[:id]) in edit method
# profiles_controller.rb
def edit
@profile = Profile.find(params[:id])
end
I have tried to use :user_id and :profile_id but that also gave error "Couldn't find Profile without an ID"
EDIT 2-
routes.rb has, it is pretty much blank
resources :profiles
rake routes output (the other paths are devise standard paths)
profiles GET /profiles(.:format) profiles#index
POST /profiles(.:format) profiles#create
new_profile GET /profiles/new(.:format) profiles#new
edit_profile GET /profiles/:id/edit(.:format) profiles#edit
profile GET /profiles/:id(.:format) profiles#show
PUT /profiles/:id(.:format) profiles#update
DELETE /profiles/:id(.:format) profiles#destroy
profiles_controller.rb , the other 5 methods are standard once
def edit
@user = current_user
@profile = @user.profiles.find(params[:profile_id])
end
def create
@profile = current_user.build_profile(params[:profile])
respond_to do |format|
if @profile.save
format.html { redirect_to @profile, notice: 'User profile was successfully created.' }
format.json { render json: @profile, status: :created, location: @profile }
else
format.html { render action: "new" }
format.json { render json: @profile.errors, status: :unprocessable_entity }
end
end
end
Upvotes: 0
Views: 5626
Reputation: 4375
First fix your user model:
before_filter :create_profile
def create_profile
profile = Profile.create
end
should be:
after_create :create_profile
def create_profile
self.profile.create
end
before_filter is for controllers, not for models!
Second: Change this line
<li><%= link_to "Profile".html_safe, edit_profile_path(current_user) %></li>
to this one:
<li><%= link_to "Profile", edit_profile_path(current_user.profile) %></li>
Third: Change your controller edit action:
def edit
@profile = current_user.profile
end
I think you could remove the create action from your profiles_controller, because you have the before_create hook in your user model which creates the profile.
Your routes
resources :profiles
just provides you an id parameter for the edit action, and that´s the id from the profile, and not from the user. You could add one through nested routes for the current_user, but that´s not necessary, because you already have the current_user method from devise which returns you the current logged in user.
btw:
"Profile".html_safe
=> is not necessary.
"<h1>Profile</h1>".html_safe
=> would be necessary.
Upvotes: 2
Reputation: 11007
Not sure what your controller looks like, but you can explicitly tell rails where to find the profile_id. something like this:
<li><%= link_to "Profile".html_safe, edit_profile_path(current_user, profile_id: @profile) %></li>
Edit:
#<Class:0xb459b8c>
is the whole user class, not an instance which is why you can't call profiles
on it. try this:
@user = current_user
@profile = @user.profiles.find(params[:profile_id])
Edit 2:
According to your original question:
the problem is, I have put an edit link in application.rb
<li><%= link_to "Profile".html_safe, edit_profile_path(current_user) %></li>
but it is giving error
Couldn't find Profile with id=10
so instead of searching for id=2, it is looking at user_id, how to fix this ?
The problem, i think, is here:
`<li><%= link_to "Profile".html_safe, edit_profile_path(current_user) %></li>`
your `edit_profile_path' calls for
/profiles/:id/edit(.:format)
that :id
is the :id of the profile
table, not the user
table - so your link_to
should look like this:
<li><%= link_to "Profile".html_safe, edit_profile_path(id: @profile.id) %></li>
or just
<li><%= link_to "Profile".html_safe, edit_profile_path(@profile) %></li>
and your controller should look like this (how it did originally):
# profiles_controller.rb
def edit
@profile = Profile.find(params[:id])
end
which will give your routes what they want.
Upvotes: 1
Reputation: 1051
If devise already provide edit functionality then why you need to maintain profile just for edit still if you need it you should not add user_id column in profile it should come User.
Try this:
<%= link_to "edit", edit_user_registration_path(current_user) %>
Upvotes: 2