How to use x_editable_rails for editing comments - ruby-on-rails

Not sure why i am getting this error message when implementing gem x_editable_rails to allow comments to be edited without users being brought to a separate edit page.
x_editable_rails demo app shows that perhaps the right way should be <%= editable #comment, :content %>, but because I am looping all comments in the #comments instance variable, doing that throws an error too.
EDIT
I changed the line of code from <%= editable #comments.comment %> to <%= editable [comment.article, comment], :content, url: edit_article_comment_path(comment.article, comment) %> and now, its showing
undefined method `xeditable?' error.
I have added the below helper method and added this (helper_method :xeditable?) to application controller. (I don't use cancan so i have added a dummy can? as suggested on this stackoverflow post.
module ApplicationHelper
def xeditable?
current_user.xeditable?
end
def can?(role, object)
true
end
end
_comments.html.erb
<% #comments.each do |comment| %>
<%= editable [comment.article, comment], :content, url: edit_article_comment_path(comment.article, comment) %>
<%= link_to "Delete comment", [comment.article, comment], method: :delete %>
<%= link_to "Edit comment", edit_article_comment_path(comment.article, comment) %>
<% end %>
routes.rb
resources :articles do
resources :comments
end

Routing
The original error you posted indicates you do not have a route for APP_DOMAIN/comments/:id, and that's confirmed by your routes -- comment is a nested resource in your routing, routed like APP_DOMAIN/articles/:id/comments/:id.
Note that for unusual routing (i.e. not a typical Rails naming pattern), x-editable-rails allows you to specify your path. Maybe comments are routed through another name, like url: post_critique_path(#comment.post, #comment). I see you have now done this, though I'm not sure if it is necessary since your routing is standard pratice.
Note that I have not tested this myself. The README is not super clear on what are the allowed or expected values for :url. And, confusingly, the gem has a :nested option – which appears to be about setting the title HTML attribute.
Application helper methods
For your next error, it appears you are implementing the advice from this answer. But I believe you have missed a line, and your ApplicationHelper module should look like this:
module ApplicationHelper
helper_method :xeditable?, :can
def xeditable?
current_user.xeditable?
end
def can?(role, object)
true
end
end

Related

Why is my RoR link pointing to the wrong controller action?

I have the following in my projects_controller.rb:
def destroy
#project = Project.find_by_slug(params[:id])
#project.destroy
redirect_to projects_url
end
And I have the following in my routes.rb file:
delete "projects/:id", to: "projects#destroy", as: "destroy_project"
I have the following link (inside the show.html.erb file):
<%= link_to destroy_project_path(#project), method: :delete, class: "btn-gradient btn-red" do %>
<span>Delete Project</span>
<% end %>
Upon clicking the button, the page reloads. The show action is called upon clicking the button. I've added console logs in each method, and it is clear that the destroy action is never called.
Can anyone point me in the right direction?
the link_to helper receives 2 different sets of hashes for the options.
The first set is for things like the http method, and the second for the html attributes (class, id and so on)
The way you wrote it, you probably have method=delete in your query params, which is wrong. You have to explicitly enclose the method: :delete within its own options hash:
<%= link_to destroy_project_path(#project), { method: :delete }, class: "btn-gradient btn-red" do %>
<span>Delete Project</span>
<% end %>
If you use rails 7 with turbo framework you can try below for buttons.
<%= button_to "Delete this project", destroy_project_path(#project), method: :delete %>
Or you can try below for links.
<%= link_to destroy_project_path(#project.id) , data: { turbo_method: :delete } do %>
<span>Delete Project</span>
<% end %>
the problem that you are having is with the JS. there is a problem where something is not loading properly.
For testing try to remove your JS and use something like this
<%= javascript_include_tag "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js" %>
When you get the delete method working, then you can debug where in your JS there is a problem.
at this time there is not sufficient info on your question to be able to know what it is.

No route matches [GET] "/links/1/like" acts_as_votable

The other solutions here did not work, so I am posting a new question. I am using acts_as_votable for up and down voting on links, but when I try to actually vote I get the error:
No route matches [GET] "/links/1/like"
This is what my view looks like:
<%= link_to like_link_path(link), method: :put, class: "btn btn-default btn-sm" do %>
<span class="glyphicon glyphicon-chevron-up"></span>
Upvote
<%= link.get_upvotes.size %>
<% end %>
<%= link_to dislike_link_path(link), method: :put, class: "btn btn-default btn-sm" do %>
<span class="glyphicon glyphicon-chevron-down">
Downvote
<%= link.get_downvotes.size %>
<% end %>
And this is what my routes look like:
resources :links do
member do
put "like", to: "links#upvote"
put "dislike", to: "links#downvote"
end
end
I see that my client is trying to access the get method, but I explicitly call method: :put in my index.html.erb file.
Do you know why it is trying to access get and how I can override that?
This problem is almost always to do with JQuery, although in this instance I'm not sure why.
You can even see it here:
Note that if the user has JavaScript disabled, the request will fall back to using GET
I would firstly check that you have JQuery in your app, and then that it's getting called okay. If it isn't loading, then the best course of action is to see why JQuery is not being called (it's either going to because it won't be referenced, or you'll have an error preventing it from loading).
Your code actually looks valid, so I'd have to say that JQuery would be the likely issue here.
You could polish up your routes etc:
#config/routes.rb
resources :links do
match "vote", action: :vote, via: [:put,:delete], on: :member
end
This will send both types of request to an action called vote, which you can then split up as follows:
#app/controllers/links_controller.rb
class LinksController < ApplicationController
def vote
if request.put?
# Code to vote
elsif request.delete?
# Code to downvote
end
# Redirect back
end
end
Much DRYer and more efficient (only calling a single action etc)
It turns out that the answer was related to JQuery. I was getting an Uncaught ReferenceError: jQuery is not defined error and so what I did was include JQuery outright in my application.html.erb file.
You have to put this ahead of all your other scripts.
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
After that, the voting began to work

No route matches [GET] "/links/1/like" with acts_as_votable

I'm trying to implement acts_as_votable gem as shown in this this tutorial
https://www.youtube.com/watch?v=7-1HCWbu7iU
Seems everything is workigng fine, except when I click on upvote or downvote, I get this error:
No route matches [GET] "/links/1/like"
This is the code for upvote / downvote function
<span class="upvote">
<%= link_to like_link_path(link), method: :put, class: "upvote-image" do %>
<% end %>
</span>
This is the routes.rb file:
resources :links do
member do
put "like", to: "links#upvote"
put "dislike", to: "links#downvote"
end
resources :comments
end
Here are the upvote and downvote actions in links_controller
def upvote
#link = Link.find(params[:id])
#link.upvote_by current_user
redirect_to :back
end
def downvote
#link = Link.find(params[:id])
#link.downvote_by current_user
redirect_to :back
end
Any idea on how to resolve this?
Looks like the problem is down to your link having a GET method, rather than PUT:
No route matches [GET] "/links/1/like"
I can only surmise that your link_to code is not written correctly:
<span class="upvote">
<%= link_to like_link_path(link), method: :put, class: "upvote-image" %>
</span>
Your other code looks good. If you test this, the best thing to do will be to show the pure HTML for the link in your question - this will give us the ability to see whether it's being rendered correctly.
I found an answer for this, and I'm posting it here in case there are others with the same problem.
I'm developing on Windows. I had problems with javascript, and followed this solution here:
https://stackoverflow.com/a/31972253/1690091
This removed the javascript related errors that were popping all over the place, but this is NOT the solution. This simply removed js from my app.
The real solution is here:
https://stackoverflow.com/a/28331807/1690091
You need to use a proper version of coffee script, that's compatible with Windows.
To sum things up:
js file was missing from my app, and therefore //= require jquery_ujs was also missing, and that's why all of my links were being called as GET.
#Rich Peck,
Thanks for your help.
Try this
<span class="upvote">
<%= link_to like_path, method: :put, class: "upvote-image" do %>
<% end %>
</span>

undefined method error with delete statement

For my projects I have the following relevant code
routes:
resources :lists do
resources :items
end
I now included a loop on list/show page in which I want to show the item and provide the users with the possibility to delete the item.
So i got code like this:
<% #items.each do |item|%>
<p>
Item: <%= item.name %>
<%= time_ago_in_words(item.created_at) %> ago.
</p>
<%= link_to "Delete", [#list.item, item], method: :delete %>
<% end %>
But when I try to run it I get the error:
undefined method 'item' for #<List:0x007fba7be6fe28>
While I did define the variables in my controller:
Items-controller:
def destroy
#list = current_user.list
#item = #list.items
end
Could anyone explain whats causing this error?
you have a typo in your controller - it should be #items = #list.items that's why the iteration doesn't work properly.
edit: after formatting your original question, I see that the error was raised on #list object, so you have to fix path to delete action:
<%= link_to "Delete", [#list, item], method: :delete %>
you build the path by providing the parent object (#list) and then the object itself (item) - Rails will translate it to list_item_path.
change your link_to
= link_to("Delete", lists_items_url(#list, #item), method: :delete)
You have defined resources :lists and resources :items.
Basically what you want to do is send a DELETE request to the collection with the IDs to fetch and delete the items.
Run a rake routes to check the exact naming, but I think it's written like that to be sure. Although you don't seem to be needing the IDs based on your controller's action, you still need to supply them for the helper.
You're using #items.each and in your controller have only #item.

Link_to doesn't work when using acts-as-taggable-on with custom method

Or rather I don't know how to specify the route for it.
I have my controller setup us:
def tags
#clients = current_user.clients.find_tagged_with(params[:tag])
end
and my views
Tags:
<% for tag in #client.tags %>
<%= link_to tag.name, clients_path(:view =>'tag', :tag => tag.name) %>
<% end %>
Only problem is that the link (clients_path) goes back to index and not 'all.' I know it has to do with changing the clients_path to somehow tell it to use 'all'. But I don't know how.
Any help?
Thanks
You can check your routes using rake routes.
I'm not sure what you mean by 'all' but if this is a custom method added to routes, then you should be able to use all_clients_path instead of clients_path.

Resources