Rails Tutorial 10.2 - 6: "NoMethodError in Users#edit" - ruby-on-rails

I've been walking through the Hartl tutorial for the first time and have been getting an error on Chapter 10 editing/updating users. Following along, I >>should<< be able to at least view the user edit page, but keep getting the below error. Have gone through everything a few times but can't seem to find the origin of my problem. Note that this is my first time doing anything programming related so go slow with me.
Error
undefined method `model_name' for NilClass:Class
Line being called out in error, from my user edit view
<%= form_for(#user) do |f| %>
Edit method from Users controller
def edit
#user = User.find(params[:id])
#title = "Edit user"
end
A similar block of code is used in my user new view with no issues, and am at a loss why this would be returning nil and have tried with both new and existing users . Thanks!

I just had the same issue, it looks like this happens because your "edit" action isn't defined. Could it be you have either not saved the user_controller file or forgotten to define the "edit" variable?

The error is a bit obscure. It is saying that #user in <%= form_for(#user) do |f| %> is nil. It is likely that #user = User.find(params[:id]) is not finding anything. It would be worth putting Rails.logger.debug("Id: #{params[:id]}") above #user = User.find(params[:id]) and see what is being passed for params[:id].
This SO post had a similar issue though not with the tutorial. The exception is coming from form_for.

Related

How to connect another user id with my input for that user?

Another user posts a problem, and I can click on that post to see details about that problem (not through show) and give a recommendation. The thing is that I don't want my recommendation to be linked with this problem. I want it to be linked with that user herself. To do this, I tried:
create
#recommendation = current_user.recommendations.build(recommendation_params)
#user = User.where(user: params[:user_id])
#recommendation.helped_id = #user.id
end
where helped_id should equate that user's id. (later I want that user to be able to see all recommendations she's been given)
But it's turning up error, saying
undefined method `id' for #<User::ActiveRecord_Relation:0x007ff6a9621f68> Did you mean? ids
UPDATE
So I go to the url where this other user's problem is detailed by this view code:
<% #users.each do |u| %>
<%= link_to new_recommendation_path(user_id: u.id) do %>
And the url is: http://localhost:3000/recommendations/new?user_id=2
Could this be the problem?
#user = User.find(params[:user_id]) works fine in new method for showing the problem, but the same code in create method returns cannot find.
You should use the find method which returns the object instead of a relation...
#user = User.find(params[:user_id])
It's possible to continue using AR Relation, so your code would be
#recommendation = current_user.recommendations.build(recommendation_params)
#user = User.where(id: params[:user_id]).first
#recommendation.helped_id = #user.id
Tip: In both scenarios, using User.find or User.where, you should take care of exceptional cases.
Using User.find, if user doesn't exist, then an ActiveRecord::RecordNotFound will be raised.
Using User.where, if user doesn't exist, then a NoMethodError (undefined method `id' for nil:NilClass) will be raised.
The solution was to add nested resources for user and recommendations
resources :users, shallow: true do
resources :recommendations
end
And, in the view, pass both user and recommendation parameters to the recommendation page.
<% #users.each do |u| %>
<%= link_to new_user_recommendation_path(u.id, #recommendation) do %>
Then #user = User.find(params[:user_id]) works.

Rails App - Object_ID Returning for User Name

I am developing a simple blog app and am having trouble displaying the user name associated with a comment.
Comments belongs_to :posts and :users. Posts belongs_to :user and has_many :comments. Users has_many :posts and :comments.
The create action in my comments model works and stores the comments as expected with the post_id and user_id:
class CommentsController < ApplicationController
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.create(comment_params)
#comment.user = current_user
if #comment.save
redirect_to #post
else
flash.now[:danger] = "error"
end
end
private
def comment_params
params.require(:comment).permit(:content)
end
end
I am able to access the user name via the console as expected with Comment.first.user.name which returns the users name. When trying to do this in the view, I get the following error:
undefined method `name' for nil:NilClass
Here is the view:
<% #post.comments.each do |comment| %>
<p>User:<%= comment.user.name %></p>
<p>Comment:<%= comment.content %></p>
<% end %>
When I remove the .name from the user in the view, the app displays what looks to be the object_id.
User:#<User:0x00000001f62830>
Comment:Test comment
I've tried resetting the database mentioned here: Show username when posting comments in Rails
I've also tried to address the proxy_id mentioned here: Returning issue in Comment::ActiveRecord_Associations_Collection
I'm not sure what else to try. Also, when I reset the comments table so there is no data in it, the app still displays:
User:
Comment:
when it loops through even though there is no data in it. I think it has to do with the dynamic finder confused by the id, but I tried moving it all to the controller as mentioned here, retrieving username with find_by_id(comment.user_id).name not working, and I still am getting undefined method errors. Any ideas? Appreciate the insight. I am not using a comments gem, am developing in cloud9, and am using PostgreSQL.
I found the issue in this post: Using <%= render comments %> always outputs an empty partial, even if there is nothing in the database
"The issue is that the form is above the <%= render #post.comments %> so there is an empty comment when you reach the partial for all the comments, even if there's none in database, put the <%= render "comments/form" %> below to fix this."

rails3 show not getting :user_id in one case

I have a strange problem. I've been coding in Rails for, off and on, a year. I created a new project recently and used scaffolding. Things were going fine, yesturday I started implementing some favoriting features. Now I have a strange problem. I rolled back the stuff I did last night but still have the problem. First
Entry belongs to user
User has many entries
My Entry show method in my controller is very standard and simple
def show
#user = User.find(params[:user_id])
#entry = #user.entries.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render :json => #entry }
end
end
When I view the entry from a normal link in the entries index
<%= link_to 'Show', user_entry_path(#user, entry) %>
I takes me to where it should go:
/users/4/entries/11
When I create new things still look good
/users/4/entries/new
Until I click "create entry" or the submit button
<div class="actions">
<%= f.submit %>
</div>
Then it goes to
/entries/20 ...with the error:
ActiveRecord::RecordNotFound in EntriesController#show
Couldn't find User without an ID
If I go back to the entries index however, the file new entry is there and the show link takes me to the right place. Thoughts? Your help is appreciated!
The error message tells you that User.find(params[:user_id]) couldn't find a user with that ID. Try checking the structure of the GET parameters in the server logs.
If your GET path is /entries/20, then the path only has an entry ID and is missing a user ID. You might be able to fix this in your Controller#create by having it redirect to user_entry_path instead of entry_path.
How does your form look like?
I think you have nested routes? Your form should look like following:
<%= form_for [#user, #entry] do |f| %>
<% # your fields %>
<% end %>
Your form seems to point to resources entry, instead of the nested ressource..

Form_for Gives Wrong Outputs After render :action=>'edit'

I think this question might have been asked before, but I honestly don't know how to search for it.
Basically, when I do a render :action => 'edit' in the update action in controller, somehow the view outputs the form as if it's a :action => 'new' page.
form_for gave the wrong action and f.submit gave wrong button text (it gave create instead of update)
edit:
relevant parts of controller
def edit
#user = User.find_by_email(current_user.email)
end
def update
old_password=params[:user].delete(:old_password)
#user=User.new(params[:user])
if User.find_by_email(#user.email).valid_password?(old_password)
logger.info 'Valid old password'
else
flash[:notice]='Invalid current password'
render :action=>'edit'
end
end
As discussed in the comments, #bassneck is right - while you are rendering the edit view, the form_for call looks at whether the object is persisted or not (#user.persisted?). This has the benefit in a lot of cases of being able to use one piece of form code for both new and edit views (I'll generally have a partial _form.html.erb that gets used for both situations).
In your case though, it isn't leading to the desired behaviour - so wwhat you need to do is make sure you're using the relevant user object. If you want to update a user, #user should be the object you want to update.

uninitialized constant with rails friendships

I'm new to rails and getting the following error:
NameError in FriendshipsController#create
uninitialized constant FriendshipsController
this also shows up:
{"authenticity_token"=>"eQvv3flATE+P1TEErOWP/6fM8dEOIBxltobCxtM/F18=",
"friend_id"=>"32"}
When I click on the "Add Friend" Link on my users show page. I am following the railscast about self referential associations to a T, but I keep getting this error and I can't find any information about it, not even what "uninitialized constant" means. I've gathered from the internet that it MAY be related to the acts_as_authenticated plugin, but I followed the one fix I found and it didn't work.
Here is the code from my user/show.html.erb page:
<%= link_to "Add Friend", friendships_path(:friend_id => #user.id), :method => :post %>
and the code from my friendships controller:
def create
#friendship = current_user.friendships.build(:friend_id => params[:friend_id])
if #friendship.save
flash[:notice] = "Added friend."
redirect_to root_url
else
flash[:error] = "Unable to add friend."
redirect_to root_url
end
end
Where am I going wrong here. I haven't the faintest clue what is causing this. Please let me know if I am missing any needed code.
Difficult to tell. You should post the top part of your class... requires, class definition, includes, and anything else you have that is outside of your methods, as well as the create method.
Rails is complaining because you have used a constant before initializing it.
puts SomeConstant
# before
SomeConstant = 10
In this case the constant is a controller Class Name - FriendshipsController
Check if the class name is correct, i.e. you have a controller with that name in your app\controller directory.
I think you run
rails g controller Friendship
while you should have used
rails g controller Friendships
thats why all files are now singular
You can still go through and change all files though

Resources