Missing template articles/favorite in rails - javascript

I want to add the Favorite function in my rails app. I added a partial favorite to show.html.erb, it will show the favorite link or unfavorite link, if I favorite a article, doesn't need to refresh whole page:
#app/views/articles/show.html.erb
<div class="panel-body"><p><%= markdown(#article.content) %></p></div>
<div class="panel-footer" id="favorite">
<div><%= render 'favorite_link' %></div>
...
_favorite_link.html.erb:
<% if not Favorite.where(user_id: current_user.id, article_id: #article.id).first %>
<%= link_to 'favorite', favorite_article_path(#article), {id: #article.id, method: :post}, remote: true %>
<% else %>
<%= link_to 'unfavorite', unfavorite_article_path(#article), method: :delete, remote: true %>
<% end %>
favorite.js.erb:
$("#favorite").html("<%= escape_javascript render partial: 'favorite_link' %>");
ArticlesController:
def favorite
#article = Article.find(params[:id])
#article.favorites.create(user_id: current_user.id)
render 'favorite'
end
def unfavorite
#article = Article.find(params[:id])
favorite = Favorite.where(user_id: current_user.id, article_id: #article.id).first
favorite.destroy
render 'favorite'
end
When I click favorite link, it doesn't work, error info as below:
ActionView::MissingTemplate (Missing template articles/favorite, application/favorite with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in:
* "/Users/liuxingqi/Public/Sparta/my_blog/mongo_project/app/views"
* "/Users/liuxingqi/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/kaminari-0.16.3/app/views"
):
app/controllers/articles_controller.rb:90:in `favorite'
but unfavorite works well. Hope someone can help me! Thanks in advance!

It search for a view with HTML extention no JS and what you have is favorite.js.erb, to fix that the request to favorite should be ajax request and with format: js something like
articles_favorite_path(format: :js)

I found the root cause, because the wrong parameters order, the remote: true doesn't work.
<%= link_to 'favorite', favorite_article_path(#article), {id: #article.id, method: :post}, remote: true %>
should be:
<%= link_to 'favorite', favorite_article_path(#article), {id: #article.id, method: :post, remote: true} %>

Related

undefined method `item_path' while working with ajax

Im trying to update my create item action to work with Ajax but Im getting an error of undefined methoditem_path` which i wasn't getting before when it was responding in regular html format. The item is created and saved but ajax doesn't seem to work properly though.
Here is my _from partial :
<%= form_for [#user, item], remote: true do |f|%>
<div class="form-group">
<%= f.label :name, class: 'sr-only' %>
<%= f.text_field :name , class: 'form-control', placeholder: "Enter a new item " %>
</div>
<%= f.submit "Submit Item", class: 'btn btn-primary pull-right' %>
<% end %>
item#create:
def create
#item = Item.new(item_params)
#item.user = current_user
if #item.save
flash[:notice] = 'Item saved successfully.'
else
flash[:alert] = 'Item not saved. Title is too short or missing. Please try again.'
end
respond_to do |format|
format.html
format.js
end
end
create.js.erb:
$('.js-items').prepend("<%= escape_javascript(render(#item)) %>");
$('.new-item').html("<%= escape_javascript(render partial: 'items/form', locals: {user: #user , item: #item }) %>");
User#show view
<div class='new_item'>
<%= render :partial => 'items/form', :locals =>{:item => Item.new , :user => #user} %>
</div>
<div class='js-items'>
<%= render #user.items %>
</div>
routes:
user_items GET /users/:user_id/items(.:format) items#index
POST /users/:user_id/items(.:format) items#create
new_user_item GET /users/:user_id/items/new(.:format) items#new
edit_user_item GET /users/:user_id/items/:id/edit(.:format) items#edit
user_item GET /users/:user_id/items/:id(.:format) items#show
PATCH /users/:user_id/items/:id(.:format) items#update
PUT /users/:user_id/items/:id(.:format) items#update
DELETE /users/:user_id/items/:id(.:format) items#destroy
The error im getting in rails s :
ActionView::Template::Error (undefined method `item_path' for #<#<Class:0x007fa4f0d30cd8>:0x007fa4f31b26b0>):
1: <%= form_for [#user, item], remote: true do |f|%>
2: <div class="form-group">
3: <%= f.label :name, class: 'sr-only' %>
4: <%= f.text_field :name , class: 'form-control', placeholder: "Enter a new item " %>
app/views/items/_form.html.erb:1:in `_app_views_items__form_html_erb__331698480542899910_70173200751480'
app/views/items/create.js.erb:2:in `_app_views_items_create_js_erb___3618987352886002527_70173200313760'
app/controllers/items_controller.rb:17:in `create'
Do something like that.
<%= form_for [#user, item], user_items, remote: true do |f|%>
If it doesn't work then run
rake routes
in terminal see what's your path.

Trying to destroy request via ajax for relationship entities in ruby on rails

I'm trying to delete a "budget"(in portuguese, "orçamento") via ajax request, and that budgets have a relationship belongs to cadastre and cadastre has many budgets. My components are as follows:
orcamentos_controller.rb
.
.
.
def destroy
#cadastro = Cadastro.find(params[:cadastro_id])
#orcamento = #cadastro.orcamentos.find(params[:orcamento_id])
#orcamento.destroy
respond_to do |format|
format.js { head :ok }
end
end
def index
#cadastro = Cadastro.find(params[:cadastro_id])
#orcamentos = #cadastro.orcamentos.paginate(page: params[:page], per_page: 10)
end
.
.
.
index.html.erb
... <%= render "orcamentos_lista" %> ...
_orcamentos_lista.html.erb
<table class="table">
<% #orcamentos.each do |orcamento| %>
<tr id="remove_orcamento_<%= orcamento.id %>">
<td>
<%= link_to "Orçamento nº #{orcamento.id}, registrado em #{orcamento.created_at.strftime("%d/%m/%Y")}", "#", class: "list-group-item", type: 'button'%>
</td>
<td>
<%= link_to "Excluir", orcamento, method: :destroy, remote: true %>
</td>
</tr>
<% end %>
</table>
<% content_for :js do %>
<% #orcamentos.each do |orcamento| %>
$('#remove_orcamento_<%= orcamento.id %>').bind('ajax:success',
function(){
$('#orcamento_<%=orcamento.id%>').remove();
}
);
<% end %>
<% end %>
routes.rb
.
.
.
resources :cadastros do
resources :orcamentos
end
.
.
.
I get the error undefined method orcamento_path for #<#<Class:0x007f5f39757930>:0x007f5f39cf1eb8> this line <%= link_to "Excluir", orcamento, method: :destroy, remote: true %>
I am a beginner in both ruby as on rails, so forgive me any ugliness in code.
run
rake routes
Then whatever path you want that link to have in it find it in the table of routes and use the 'prefix' for it with "_path" at the end. So if the resource you want is on that table and has a prefix of foo_bar then your link_to should have foo_bar_path used in your view.
so change this line
<%= link_to "Excluir", orcamento, method: :destroy, remote: true %>
to this
<%= link_to "Excluir", foo_bar_path, method: :destroy, remote: true %>
The problem you have is that you're calling orcamento as the link, when you've nested it within cadastros:
#config/routes.rb
resources :cadastros do
resources :orcamentos # -> url.com/cadastros/:catastros_id/orcamentos/:id
end
This means if you want to call the path helper for an orcamentos, you have to use the nested resource:
cadastros_orcamentos_path(#cadastros, orcamento)
If you're using link_to, you should be able to pass an array of the nested objects as you require:
link_to "Delete", [#cadastros, orcamento], method: :delete

Dropzone.js with Rails 4: "Template is missing" error

I'm trying to use Dropzone.js with Rails 4, and although I can get the actual Dropzone 'zone' to appear, when I try to upload images, the following
Template is missing Missing template projects/show, application/show with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}
However, I'm quite sure that I have the template, as images that are being uploaded without Dropzone are uploading and displaying fine
My code is as follows:
ProjectImagesController:
class ProjectImagesController < ApplicationController
def create
#project = Project.find(params[:project_id])
#project_image = #project.project_images.create(project_image_params)
redirect_to project_path(#project)
end
private
def project_image_params
params.require(:project_image).permit(:caption, :image)
end
end
projects/show.html.erb
<% if #project.project_images.any? %>
<% #project.project_images.each do |project_image|%>
<ul>
<li><%= image_tag project_image.image.url(:thumb) %></li>
<li><%= project_image.caption %></li>
</ul>
<% end %>
<% end %>
<%= simple_form_for [#project, #project_image], :html => {:multipart => true, class: :dropzone} do |f| %>
<div>
<%= f.input :caption, label: 'Enter your project image caption' %>
<%= f.file_field :image %>
<%= f.submit 'Create project image'%>
</div>
Thank you for your help in advance.
dropzone sends request in JSON format, but you try to render HTML, so you have to change your controller:
from
def create
#project = Project.find(params[:project_id])
#project_image = #project.project_images.create(project_image_params)
redirect_to project_path(#project)
end
to
def create
#project = Project.find(params[:project_id])
#project_image = #project.project_images.create(project_image_params)
render nothing: true
end
or something else in JSON format
hope I'll help somebody...

Ruby on Rails Like button with image instead of text

I am currently working with the Acts_As_Votable gem in Ruby to use a Like link on each of my posts so that users can vote. I found a great answer on here that helped be do exactly that but I'm trying to figure out how I can use a heart icon image instead of the Like/Dislike text. I want the image to update without refreshing, just like the text links do but can't figure out the logic. Here is the current code I am using:
controllers/prides_controller.rb
def like
#pride = Pride.find(params[:id])
#pride.liked_by current_user
if request.xhr?
render json: { count: #pride.get_likes.size, id: params[:id] }
else
redirect_to #pride
end
end
def dislike
#pride = Pride.find(params[:id])
#pride.disliked_by current_user
if request.xhr?
render json: { count: #pride.get_likes.size, id: params[:id] }
else
redirect_to #pride
end
end
prides/show.html.erb
<div class="single-heart-this">
<% if current_user.liked? #pride %>
<span class="heart-icon-loved">
<%= link_to "Dislike", dislike_pride_path(#pride), class: 'vote', method: :put, remote: true, data: { toggle_text: 'Like', toggle_href: like_pride_path(#pride), id: #pride.id } %></span>
<% else %>
<span class="heart-icon">
<%= link_to "Like", like_pride_path(#pride), class: 'vote', method: :put, remote: true, data: { toggle_text: 'Dislike', toggle_href: dislike_pride_path(#pride), id: #pride.id } %></span>
<% end %>
<span class="heart-no" data-id="<%= #pride.id %>"><%= #pride.get_likes.size %></span>
<% end %>
</div>
javascript/pride.js.erb
# Rails creates this event, when the link_to(remote: true)
# successfully executes
$(document).on 'ajax:success', 'a.vote', (status,data,xhr)->
# the `data` parameter is the decoded JSON object
$(".heart-no[data-id=#{data.id}]").text data.count
return
javascript/prides.js.coffee
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
$(document).on 'ajax:success', 'a.vote', (status,data,xhr)->
# update counter
$(".heart-no[data-id=#{data.id}]").text data.count
# toggle links
$("a.vote[data-id=#{data.id}]").each ->
$a = $(this)
href = $a.attr 'href'
text = '$a.text()'
$a.text($a.data('toggle-text')).attr 'href', $a.data('toggle-href')
$a.data('toggle-text', 'text').data 'toggle-href', href
return
return
Thanks for your help.
Try this?
Add: class: "Change_me" to your link
<%= link_to image_tag("Dislike.png"), dislike_pride_path(#pride), class: 'vote', method: :put, remote: true, data: { toggle_href: like_pride_path(#pride), id: #pride.id }, class: "change_me" %>
src: link_to image_tag with inner text or html in rails
In your coffeescript, change the image src
$(".change_me").attr 'src', '/like.png'
src: Rails 3.1 CoffeeScript/JQuery - How to change the source of an image in a div?

Ajax/Rails Nested Comments

I have an application where book_comments belongs_to books.
My routes file :
resources :books do
resources :book_comments
end
I have a book_comment form on show.html.erb for books.
def show
#book = Book.find(params[:id])
#new_book_comment = #book.book_comments.build
end
I'm using ajax to post the book_comments to the book show page via a partial: _book_comment_form.html.erb :
<%= form_for([#book, #new_book_comment], remote: :true) do |f| %>
<div class="field" style="margin-top:60px;">
<%= f.text_area :comment, rows: 3 %>
<%= f.submit "Add Comment" %>
</div>
<% end %>
When #new_book_comment is called it refers to a book_comments_controller create action:
def create
#book = Book.find(params[:book_id])
#book_comment = current_user.book_comments.build(params[:book_comment]) do |f|
f.book_id = #book.id
end
if #book_comment.save
respond_to do |format|
format.html { redirect_to #book }
format.js { render :layout => false }
end
end
end
The book_comment is saved but my problem comes in when trying to render via ajax in the _book_comments partial:
<div id="comments">
<% #book_comments.each do |book_comment| %>
<%= render 'comment', :book_comment => comment %>
</div>
<% end %>
</div>
via: create.js.erb in the book_comments folder
$("div#comments").append("<%= escape_javascript(render('books/comment'))%>")
To sum, I'm having trouble making the create.js.erb in book_comments render to the book show page. Why wouldn't create.js.erb in the book_comments folder know to look at the objects in the and infer the new book comment should go inside the div?
My error message:
undefined method `comment' for nil:NilClass
don't understnd why. Seeing that I'm passing the instance variable to the comment partial.
Your partial's doing it wrong. You're passing a not referenced value (comment) to a not used variable (book_comment).
Instead of:
<% #book_comments.each do |book_comment| %>
<%= render 'comment', :book_comment => comment %> ....
you should do:
<% #book_comments.each do |book_comment| %>
<%= render 'comment', :comment => book_comment %>

Categories

Resources