Rails: Using Ajax - ruby-on-rails

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!

Related

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.

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.

Model index.html page displaying duplicated data

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.

ruby printing database content

I am new in Ruby.
I have to render the database structure, using tutorial i found suitable code:
File index.html.erb:
<h1>Listing tasks</h1>
<table>
<tr>
<th>Title</th>
<th>Content</th>
<th>Date From</th>
<th>Date To</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #tasks.each do |task| %>
<tr>
<td><%= task.title %></td>
<td><%= task.content %></td>
<td><%= task.datefrom %></td>
<td><%= task.dateto %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Destroy', task, :method => :delete, :data => { :confirm => 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Task', new_task_path %>
Now i want to group tasks by 'date from' value, probably it means that in index.html.erb i should print only dates, and clicking on the date i should call another html file that will render tasks by chosen date.
this can be like
File index.html.erb:
<h1>Listing dates</h1>
<table>
<tr>
<th>Date From</th>
<% #tasks.each do |task| %>
<tr>
<td><%= !!! IF DATE NOT PRINTED THEN PTINT IT task.datefrom %></td>
<td><%= link_to 'Edit', edit_date_path(task, date) %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Task', new_task_path %>
Where edit_date_path(task, date) should refer me to the index_date.html.erb, where i can get selected date and print tasks according to selected date.
Maybe i can get suggestion, it will be much easier is fomebody can help me with that, as task should not be very difficult, but otherwise i can waste quite a lot of time googling.
Thanks,
Urmas.
Editing the question.
This helped a little. what i did now, i changed index.html.erb to
<h1>Listing dates</h1>
<table>
<tr>
<th>Date To</th>
<th></th>
</tr>
<% dates = Array.new %>
<% #tasks.each do |task| %>
<% if ( !dates.include?(task.dateto.strftime("%m.%d.%Y")) ) then
dates.push task.dateto.strftime("%m.%d.%Y")
%>
<tr>
<td><%= task.datefrom.strftime("%m.%d.%Y") %></td>
<td><%= link_to 'Show Date', {:action => "index", :date => task.dateto} %></td> <-- This does not work
</tr>
<%
end
%>
<% end %>
</table>
<br />
<%= link_to 'New Task', new_task_path %>
Where 'Show Date' link link should be made to show_date.html.erb, where is correct code for showing records when input date is passed.
I had added in controller also method
def show_date
#tasks = Task.find(params[:dateto])
#dateto = :dateto
respond_to do |format|
format.html # showdate.html.erb
format.json { render :json => #tasks }
end
end
that can be used in the not working link, to pass data to the 'Show Date' (show_date.html.erb), but i get errors all the time. The problem is with correct calling off the show_date.html.erb, code i will be able to write myself :)
Urmas
in Tasks controller:
add a method
def index_date
#tasks = Task.all
end
and create a index_date.html.erb write
<% #tasks.each do |task| %>
<tr> <td><%= task.datefrom %></td>
<td><%= link_to 'Edit', {:action => "index", :date => task.datefrom} %></td>
</tr>
<%end%>
and in the index method in the controller change
#tasks = Task.all to
#tasks = Task.find_all_by_datefrom(#{params[:date])
This will list the tasks that match the date selected and everything will be similar as it is now thereafter.
Found the solution.
It were necessary to add to routes.rb
resources :tasks do
member do
get 'showdate'
end
get "home/index"
end
add corresponding controller processing
def showdate
#task = Task.find(params[:id])
#tasks = Task.find(:all)
respond_to do |format|
format.html # showdate.html.erb
format.json { render :json => #tasks }
end
end
and to call it using (index.html.erb)
<td><%= link_to 'Show Date', showdate_path(task.id) %></td>
All further processing is already in showdate.html.erb.
Hope this helps somebody.
I AM THE BEST!!!! xD

Rails 3 task scopes?

I am working on a simple rails 3 todo application and I am trying to filter the app by completed tasks and none completed task but whenever I try calling a scope I get the error message.
undefined method `completed' for #<Array:0x007fe8420d0e58>
task.rb
scope :completed , where(:completed => true)
scope :incomplete , where(:finished => false)
index.html.erb
<table>
<tr>
<th>Name</th>
<th>Description</th>
<th>Finished</th>
<th>User</th>
</tr>
<% #tasks.each do |task| %>
<tr>
<td><%= task.name %><%= button_to "complete", complete_task_path(task.id)%></td>
<td><%= task.description %></td>
<td><%= task.finished %></td>
<td><%= task.user_id %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Destroy', task, confirm: 'Are you sure?', method: :delete %></td>
</tr>
<% end %>
</table>
<%= content_tag :h2, "Stuff Ive done" %>
<table>
<tr>
<th>Name</th>
</tr>
<% #tasks.completed.each do |task| %>
<tr>
<td><%= task.name %></td>
</tr>
<% end %>
</table>
task_controller.rb
def complete
#task = Task.find(params[:task_id])
#task.completed = true
#task.save
redirect_to task_path
end
routes.rb
match "tasks/:id/complete" => "task#complete", :as => :complete_task
Any reasons why rails is giving me this error?
Just by looking at your view (index.html.erb), in one place, you are treating as a relation.
<% #tasks.each do |task| %>
Later in the code, you are trying to access it as a single object.
<% #tasks.completed.each do |task| %>
Since you are seeing the error on the second instance, you need to access 'completed' as in:
<% #tasks.completed.each do |task| %>
<% completed = task.completed %>
<% completed.each do |com| %>
Does this make sense?

Resources