Model index.html page displaying duplicated data - ruby-on-rails

I'm getting some strange behavior on my model index page. When I create one model object, it displays correctly on the index page. When I create a second model object, it shows duplicates of both objects on the index page, like so
OBJECT A
OBJECT B
OBJECT A
OBJECT B
I've confirmed that duplicate objects are not being created in my database. Also, when I destroy OBJECT B, it displays OBJECT A correctly only once.
index.html.erb
<table class="table">
<thead>
<tr>
<th>Image</th>
<th>Name</th>
<th>Description</th>
<th>URL</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<%= render #companies %>
</tbody>
</table>
_company.html.erb
<% #companies.each do |company| %>
<tr>
<td><%= image_tag company.image(:medium) %></td>
<td><%= company.name %></td>
<td><%= company.description %></td>
<td><%= company.url %></td>
<td><%= link_to 'Show', company %></td>
<td><%= link_to 'Edit', edit_company_path(company) %></td>
<td><%= link_to 'Destroy', company, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
companies_controller.rb
def index
#companies = Company.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #companies }
end
end

Change your partial to,
<tr>
<td><%= image_tag company.image(:medium) %></td>
<td><%= company.name %></td>
<td><%= company.description %></td>
<td><%= company.url %></td>
<td><%= link_to 'Show', company %></td>
<td><%= link_to 'Edit', edit_company_path(company) %></td>
<td><%= link_to 'Destroy', company, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
You need to drop the each loop in your partial.
The <%= render #companies %> renders the partial for each company but you're also looping through the companies again in each partial.
See 3.4.5 Rendering Collections at http://guides.rubyonrails.org/layouts_and_rendering.html#rendering-collections for more info

Change the <%= render #companies %> to <%= render "company" %>; your partial is being rendered multiple times, one for each company, and your partial is rendering all the companies. This will only render the partial, which will render all the companies, which is what you want.

Related

How to obtain count of comments

This is my Articles index.html.erb so far
<table>
<tr>
<th>Title</th>
<th>Text</th>
<th colspan="3"></th>
<th>Total Number of Comments Per Article</th>
</tr>
<% #articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.text %></td>
<td><%= link_to 'Show', article_path(article) %></td>
<td><%= link_to 'Edit', edit_article_path(article) %></td>
<td><%= link_to 'Destroy', article_path(article),
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
<td>Placeholder</td>
</tr>
<% end %>
</table>
<p>Total Number of Articles in database: <%= #count_of_articles %></p>
<h4>All Comments Written So Far</h>
<% #comments.each do |c| %>
<p><b><%= c.commenter %></b></p>
<p><%= c.body %></p>
<% end %>
<%= link_to 'New Article', new_article_path %>
This is my Article's index action
def index
#articles = Article.all
#count_of_articles = #articles.count
#comments = Comment.all
end
I am trying to figure out how to place the number of comments that each article has in the <td>Placeholder</td>
How do I do that?
EDIT
class Comment < ActiveRecord::Base
belongs_to :article
end
class Article < ActiveRecord::Base
has_many :comments, dependent: :destroy
validates :title, presence: true, length: { minimum: 5 }
end
by doing article.comments.count in the view you're basically running a sql query for each article in your db. Why not gather all records in your controller, and ask for the count in your view?, something like:
in the controller:
#comments_by_article = Comment.all.group_by(&:article_id)
and, in your view:
<td><%= #comments_by_article[article.id] && #comments_by_article[article.id].count || 0 %></td>
that way, rails will cache #comments_by_article in your controller, and you'll hitting the database once.
It is simply count:
<table>
<tr>
<th>Title</th>
<th>Text</th>
<th colspan="3"></th>
<th>Total Number of Comments Per Article</th>
</tr>
<% #articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.text %></td>
<td><%= link_to 'Show', article_path(article) %></td>
<td><%= link_to 'Edit', edit_article_path(article) %></td>
<td><%= link_to 'Destroy', article_path(article),
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
<td><%= article.comments.count %></td>
</tr>
<% end %>
</table>
article.comments is an ActiveRecord::Relation which extends the ActiveRecord::Calculations class containing the count method. The relation was defined in your model by you. Internally, ActiveRecord will call a COUNT SQL query to determine the number of comments that matches your article.
You can get the count with
article.comments.count

Filter paginated posts by date introduced by user (Rails)

I have the post_controller with index method like this:
def index
#posts = Post.paginate(:page => params[:page], :per_page => 3)
end
and in app / views / posts / index.html.erb i have:
.
.
.
<table>
<tr>
<th>User</th>
<th>Post</th>
<th>Date</th>
<th colspan="3"></th>
</tr>
<% #posts.each do |post| %>
<tr>
<td><%= post.user.id %></td>
<td><%= post.text %></td>
<td><%= post.created_at %></td>
<td><%= link_to 'Show', post_path(post) %></td>
<% if can? :update, post %>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<% end %>
<% if can? :destroy, post %>
<td><%= link_to 'Destroy', post_path(post),
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
<% end %>
</tr>
<% end %>
<%= will_paginate #posts %>
</table>
So i want a field in this view, where an user can input a date and the view shows all posts wich were created on that date onwards. (Posts date > date_by_user). I tried with "where" method but i couldnt. I dont want to use any gem. So, what is the best and simple way to do that?
You can search records in index method like below.
date_to_search = Date.parse('2015/1/1')
Post.where(
'created_at>=? and created_at<=?',
date_to_search.beginning_of_day
)
created_at is saved as UTC in rails, so you need to specify datetime. Not only date, to get correct data in your local time.

Ajax edit page in index

I have this page Index page:
<h1>Listing users</h1>
<table border="1">
<tr>
<th>Name</th>
<th>Description</th>
<th>Who</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td><%= user.description %></td>
<td><%= user.who %></td>
<%= render 'users/form' %>
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New User', new_user_path %>
Scaffold controller
def index
#users = User.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #users }
end
end
I need to edit user in index page, not to go url /users/2/edit, stay on users page.
How I do this in Ajax?
Add remote:true to the Edit line in order to make an ajax call:
<td><%= link_to 'Edit', edit_user_path(user), remote:true %></td>
Also, add an edit.js.erb file (a javascript file with embedded ruby) in which you do all the javascript actions to be executed after the Edit. That edit.js.erb file is generated when the edit method is done. This is where you write all the changes to the javascript code which affect the current page (the page will not be re-rendered).
Additionally, add the following to the edit method:
respond_to do |format|
format.js
end

undefined method `map' for nil:NilClass in Rails with Paperclip

This will be my last question for today (sorry if I'm asking too fast)
I'm getting the error undefined method 'map' for nil:NilClass
It says the problem is on this line: <td><%= image_tag #map.map.url %></td>
The whole index code is below:
<h1>Listing maps</h1>
<table>
<tr>
<th>Carname</th>
<th>Map</th>
<th>Criticalcomponentlocations</th>
<th>Warnings</th>
<th>Additionalinfo</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #maps.each do |map| %>
<tr>
<td><%= map.carname %></td>
<td><%= image_tag #map.map.url %></td>
<td><%= map.criticalcomponentlocations %></td>
<td><%= map.warnings %></td>
<td><%= map.additionalinfo %></td>
<td><%= link_to 'Show', map %></td>
<td><%= link_to 'Edit', edit_map_path(map) %></td>
<td><%= link_to 'Destroy', map, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Map', new_map_path %>
Maps Controller, Index:
def index
#maps = Map.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #maps }
end
end
In your #maps.each loop, you're trying to access a (probably) non-existent #map instance variable when you should be accessing the map variable that is local to your loop.
Try this instead:
<% #maps.each do |map| %>
<tr>
...
<td><%= image_tag map.map.url %></td>
...
</tr>
<% end %>
The variable you wish to use, map, is not an instance variable. It is a local variable, so you should use 'map.url' instead of '#map.map.url'
Your line of code <td><%= image_tag #map.map.url %></td> uses an instance variable #map, but you're inside the scope of the enumerator <% #maps.each do |map| %>. You should use the map.url local variable instead of #map.map.url.

Rails: Using Ajax

Problem: Trying to implement "like" function on my blog
PostIndex:
<% #posts.each do |post| %>
<tr>
<td><%= post.name %></td>
<td><%= link_to post.content, post %></td>
<td><%= post.created_at.strftime("%Y/%m/%d, %I:%M%p") %></td>
<td><%= post.view %></td>
<td><%= post.like %></td>
<td><%= post.hate %></td>
<td><%= link_to 'like', like_post_path(post), :remote => true %></td>
</tr>
<% end %>
PostController:
def like
#post = Post.find(params[:id])
#post.like += 1
#post.save
respond_to do |format|
format.js
end
end
app/views/posts/like.js.erb
$('#post').html("<%=j #post.like %>");
Question:
I believe I'm not correctly pointing at the post I'm looking at in like.js.erb.
In the index file, Simply doing <%= #post.view %> worked. But how do you do it in like.js.erb?
You need some identifier for post's like count in your html when you want to update it after ajax call
PostIndex:
<% #posts.each do |post| %>
<tr>
<td><%= post.name %></td>
<td><%= link_to post.content, post %></td>
<td><%= post.created_at.strftime("%Y/%m/%d, %I:%M%p") %></td>
<td><%= post.view %></td>
<td id= "post<%= post.id %>_like"><%= post.like %></td> <!-- set id (identifier) here -->
<td><%= post.hate %></td>
<td><%= link_to 'like', like_post_path(post), :remote => true %></td>
</tr>
<% end %>
then in your app/views/posts/like.js.erb,
<% if #post.errors.blank? %>
$("#post<%= #post.id %>_like").html("<%=j #post.like %>");
<% end %>
Complete Way of Using Ajax to Fix a Table Row:
In your show.html (or index.html) file, you probably have a table already.
<tr>
<td>row 1</td>
<td>row 2</td>
<td>row 3</td>
</tr>
Let's pretend the rows represent some kind of variable. Then the table above would be like,
<tr>
<td><%= #variableA %></td>
<td><%= #variableB %></td>
<td><%= #variableC %></td>
</tr>
I want to change variableA without reloading the whole page. So I use Ajax.
My method:
def fixvar
#variableA = 2
end
You have to add one component to use Ajax.
def fixvar
#variableA = 2
end
respond_to do |format|
format.js
end
And wherever you want, you will have a link that will invoke the change via ajax.
<%= link_to 'change variable A', URLof_fixvar(#variableA), :remote => true %>
By using the option :remote => true, you're using an ajax component in your link_to method. You have to set URLof_fixvar in config/routes.rb accordingly. routing
Let's specify where to update in the table.
<tr>
<td id="variable_change_<%= #variableA.id %>><%= #variableA %></td>
<td><%= #variableB %></td>
<td><%= #variableC %></td>
</tr>
We did as above to specify the row that we're trying to update. For example, the row is now defined as variable_change_1. (assuming variableA.id is 1)
Now, you need to go to the related views folder, and create a .js.erb file that relates to the defined method above. For example, I had "like" method defined in my PostController, so I created
app/views/posts/like.js.erb
In here, you only need one line of code:
$("#variable_change_<%= #variable.id %>").html("<%= #variableA %>");
The first part before .html is pointing at the specified row, and the part after is the value that we want to update. Done!

Resources