I am working a on rails 3 project and am trying to render a partial on the user profile page. Rendering works fine for everything except photo. When I try to access a user profile page I get the following error
undefined methodmodel_name' for NilClass:Class`
user show.html.erb
def show
#user= User.find(params[:id])
#photo = Photo.find_by_id(params[:id])
end
In the profile show.html.erb
<%= content_tag :h2, "My photos" %>
<% photo = #user.photos %>
<% if photo.blank? %>
<%= link_to 'Create photo', new_photo_path %>
<% else %>
<%= render :partial => 'photos/photo', :locals => {:photo => #photo} %>
<% end %>
Here is the partial that it is rendering
<%= div_for photo do %>
<table>
<tr>
<th>Title</th>
<th>Date</th>
<th>Extra</th>
</tr>
<tr>
<td><%= photo.title %></td>
<td><%= photo.date %></td>
<td><%= photo.extra %></td>
<td><%= link_to 'View photos', photo %></td>
</tr>
</table>
<% end %>
Any ideas or suggestions on how I can get rid of this error? Thanks in advance
The error is thrown because in :locals => {:photo => #photo}, #photo is null
Note that you are sending the list #user.photos, not a single image.
Here #photo = Photo.find_by_id(params[:id]) you are getting the photo by id, photo_id. I believe you want to find the user's photo
#photos = #user.photos
#for only one photo, also you need to make sure its not null
#photo = #user.photos.first
There isn't photo with this id in database #photo = Photo.find_by_id(params[:id])
And, therefore, you sending nil object to partial. If you want to show all user photos, try this.
<%= content_tag :h2, "My photos" %>
<% photos = #user.photos %>
<% if photos.empty? %>
<%= link_to 'Create photo', new_photo_path %>
<% else %>
<% photos.each do |photo| %>
<%= render :partial => 'photos/photo', :locals => {:photo => photo} %>
<% end %>
<% end %>
When using the div_for note is nil so I would try accessing it by iterating through the code Like I've done below. Then photos should be accessible now.
<% #photos.each do |photo| %>
<%= div_for photo do %>
Code here
<% end %>
<% end %>
Related
I have a form set up with the following code:
<h2>Add collaborators to the wiki </h2>
<table>
<tr>
<th>Name</th>
<th>Email</th>
<th>Give Access</th>
</tr>
<tr>
<%= form_for (#collaboration) do |f| %>
<% #users.each do |user| %>
<td><%= user.name %></td>
<td><%= user.email %></td>
<td> <%= f.collection_select :user_id, User.all, :id, :name, prompt: true %> </td>
</tr>
<%= f.submit %>
<% end %>
</table>
<%= f.submit %>
<% end %>
And my routes are set up like this:
resources :wikis do
resources :collaborations
end
And in my controller I defined my variables like this:
def new
#wiki = Wiki.find(params[:wiki_id])
#collaboration = #wiki.collaborations.new
end
But when I visit the page clicking on a link I created
<%= link_to 'Add Collaborator', new_wiki_collaboration_path(#wiki) %>
I still get this error:
undefined method `collaborations_path' for #<#<Class:0x007f8b6a5a8a00>:0x007f8b67820c90>
Any thoughts on what goes wrong here?
Your form here just goes to collaboration_path which you've not defined.
<%= form_for (#collaboration) do |f| %>
<% end %>
You need to include the wiki
<%= form_for ([#wiki, #collaboration]) do |f| %>
<% end %>
I'd like to create a page where I can edit all my entries at once.
For example, I have 10 devices, at that point, I'm creating a html table with at each row a device with the possibility to edit each line without having to do extra clicking.
I've already tried these things (index.html.erb)
<% #devices.each do |device| %>
<%= render 'form', locals: { device: #device }%>
or
<%= render 'form', :collection => :device %>
or
<%= render 'form', :device %>
<% end %>
And my form partial
<%= form_for #device do |f| %>
<td><%= f.submit %></td>
<td><%= f.name%></td>
<td><%= f.type</td>
<td>Style app</td>
<td></td>
<td></td>
<% end %>
But I'm still getting this error
undefined method `model_name' for NilClass:Class
Does anyone have a clue?
Thanks
From what you have tried it looks like you are very close. What if you try rendering it as a partial?
<% #devices.each do |device| %>
<%= render partial: 'form', locals: { device: device } %>
<% end %>
Another difference here is the scope of the device param on the second line.
You need to change your partial... You are rendering global variable, you need to render local variable...
So, this is your solution:
<% #devices.each do |device| %>
<tr>
<%= render 'form', locals: { device: device }%>
</tr>
and
<%= form_for device do |f| %>
Here, you should only be using the # in #devices... Nowhere else.
Edit: Don't forget your <tr></tr>
Whenever I'm trying to render the games partial, the view it's being rendered in gives a nil return.
here is the games partial:
<%= flash[:notice] %>
<tr>
<% #games.each do |game| %>
<td><%= game.name %></td>
<td><%= link_to('Pick!', vote_up_game_path(game.id), :method => :post) %></td>
</tr>
<% end %>
You should pass #games as a local variable to the partial. Consider looking at the documentation on its usage. I also feel the flash-notice should not belong inside the partial. You might also want to correct your code
<% games.each do |game| %>
<tr>
<td><%= game.name %></td>
<td><%= link_to 'Pick!', vote_up_game_path(game.id), :method => :post %></td>
</tr>
<% end %>
You would render the partial as follows
<%= render :partial => "game_partial", :locals => { :games => #games } %>
It is also important to ensure #games isn't nil. If it is, you will still get your error - you should check your controller; typically I'd imagine your controller would have #games = Game.all, of course this is dependent on your particular implementation.
I've checked out a lot of questions for putting multiple objects on one form, but they seem to be out of date.
I have a bunch of user objects:
def index
#users = User.all
#user = current_user
end
that I need to edit in a form. They all have roles which will be edited on the form. The form is rendered in a partial, and nothing shows up, just 'admin form' plaintext.
users/_admin.html.erb
admin form
<% form_for "user[]", :url => users_path do |f| %>
<ul>
<li class="layout">
<div class="header"><h2>Users</h2></div>
<table>
<thead>
...
</thead>
<tbody>
<% #users.each do |user| %>
<% puts "USER #{user}" %>
<tr>
<td><%= f.check_box(:editor) %></td>
<td><%= f.check_box(:admin) %></td>
<td><%= user.first_name %> <%= user.last_name %></td>
<td><%= user.email %></td>
</tr>
<% end %>
</tbody>
</table>
</li>
</ul>
<%= submit_tag "Save"%>
<% end %>
Just the plaintext is rendered, but no form. Any ideas on how to fix it? I've tried the suggestions in these posts: one two three, but they're out of date.
Thank you.
You need to use <%= .. %> in Rails 3.1:
<%= form_for "user[]", :url => users_path do |f| %>
Hi I worked through Michael Hartl's RAILSTUTORIAL book and I have a question about how he builds the user's show page.
The page is supposed to list all the posts a user has made.
UsersController
def show
#user = User.find(params[:id])
#posts = #user.posts.paginate(:per_page => "10",:page => params[:page])
#title = #user.name
end
users/show.html.erb
<table class="profile" summary="Profile information">
<tr>
<td class="main">
<h1><%= #user.name %></h1>
<%= render 'follow_form' if user_signed_in? %>
<% unless #user.posts.empty? %>
<table class="posts" summary="User posts">
<%= render #posts %> # this goes to posts/_post and sends the object as post
# that makes the _post view use a local variable correct?
</table> # is there a way to do with with an #post variable?
<%= will_paginate #posts %>
<% end %>
</td>
<td class="sidebar round">
<%= link_to avatar_for(#user), #user.avatar.url %><br />
<strong>Name</strong> <%= #user.name %><br />
<strong>URL</strong> <%= link_to user_path(#user), user_path(#user) %>
<strong>Posts</strong> <%= #user.posts.count %>
<%= render 'shared/stats' %>
</td>
</tr>
</table>
posts/_post.html.erb
<tr>
<td class="post">
<span class="title"><strong><%= link_to post.title, post %></strong></span><br />
<span class="timestamp">
Posted <%= time_ago_in_words(post.created_at) %> ago. </span>
Likers<span id="likers"><br />
</span>
</td>
<% if current_user?(post.user)%>
<td>
<%= link_to "delete", post, :method => :delete,
:confirm => "You sure?",
:title => post.content %>
</td>
<%end%>
</tr>
I need to render a partial in the users view that uses the post object, but it asks for it as #post and since no #post has been defined in the show action of the user's controller I get a nil error.
It seem odd to me to go from the user's controller to the posts view and use a local variable, which if I understand local variables correctly can't be used outsider that view. Is there a way to assign the value of post in that view to #post in the users view?
Thanks for the help
You need to use a local variable in the partial, and assign it in the locals hash. This line is a shortcut for iterating through the array and rendering the partial. I'm not sure if this works anymore in Rails 3:
<%= render #posts %>
The way I would do it:
<% #posts.each do |post| %>
<%= render 'posts/post', :post => post %>
<% end %>
The slightly older way of rendering partials:
<% #posts.each do |post| %>
<%= render :partial => 'posts/post', :locals => {:post => post} %>
<% end %>