Trouble with deleting my blog posts using the UI - ruby-on-rails

I am very new to Ruby on Rails so apologies, as this may be a silly question to post here.
I have made a blog (using generate scaffold). I have a few pages to interact and edit blog posts, starting with a main page which displays all blog posts ("index"), an area to view a specific blog post ("show"), and area to edit a blog post ("edit"), and an area to create a new blog post ("new").
I've also created comments (again using generate scaffold) to be applied to relevant blog posts. Comments, and a partial form for comments appears on the "show" page.
I have been working away on the whole thing to get it working nicely, but have recently realised that delete buttons that I had on the "index" page aren't working. Instead of prompting confirmation for the delete, I'm simply taken to the "show" of the relevant post.
Here is a snippet of the index "index" page:
<% #posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= post.content %></td>
<td><%= image_tag "work/thumbnails/#{post.image}", :alt => '' %></td>
<td><%= time_ago_in_words(post.created_at) %> ago (<%= post.created_at %>)</td>
<td class="zero-out"><%= link_to 'Show', post, :class => "submit-button" %></td>
<td class="zero-out"><%= link_to 'Edit', edit_post_path(post), :class => "submit-button" %></td>
<td class="zero-out"><%= link_to 'Destroy', post, confirm: 'Are you sure?', :method => :delete, :class => "submit-button" %></td>
</tr>
<% end %>
And here is the snippet of code from the posts_controller relevant to the delete:
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
format.json { head :ok }
end
end
I have also found that the remove comment buttons (on the "show" page alongside each comment) have stopped working with an error message:
Unknown action
The action 'show' could not be found for CommentsController
For reference the code for the "remove comment" button is:
<%= link_to 'Remove Comment', [comment.post, comment],
:confirm => 'Are you sure?',
:method => :delete %>
And the snippet of code in the comments_controller is:
def destroy
#post = Post.find(params[:post_id])
#comment = #post.comments.find(params[:id])
#comment.destroy
redirect_to post_path(#post)
end
I lack the full knowledge of how RoR works, and how these files interact with each other fully to troubleshoot the problem, so any help would be very much appreciated.

First you miss the arrow in the destroy link method call
Correct it to this.
<%= link_to 'Destroy', post, confirm: 'Are you sure?', :method => :delete, :class => "submit-button" %>
Second you don't have to find the post of a comment to delete it simply do this.
If you want to be redirected back to the post, you do it in the controller
<%= link_to 'Remove comment', comment, confirm: 'Are you sure?', :method => :delete %>
in the comment_controller
def destroy
#comment = Comment.find(params[:id])
#post = #comment.post
#comment.destroy
respond_to do |format|
format.html { redirect_to #post }
format.json { head :ok }
end
end

I've found the problem - I had customised the links to stylesheets, javascript files etc and in doing this I had left out links to the javascript files for posts and comments created by the scaffold.
After including links to these files everything worked again.

Related

Nesting under the Devise in Rails4

I have a problem with Controller Show Product. Can anyone help me out?
No route matches {:action=>"show", :controller=>"products", :id=>nil, :vendor_id=>"3"} missing required keys: [:id]
<td>
<%= link_to 'Show', vendor_product_path(current_vendor, #product) %><br>
<%= link_to 'Edit', edit_product_path(product) %><br>
<%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %>
</td>
my controller in product
def show
#product = Product.find(params[:vendor_id])
end
If you're trying to find all the products for a specific vendor, it would be something like:
def show
#vendor_products = Vendor.find(params[:vendor_id]).products
end
If you are just trying to find a single product by id:
def show
# Since :id is currently nil in params, this will not work
#product = Product.find(params[:id])
end
In the view, where are you getting #product from? Seems like #product is not yet saved to the database, and so it is nil in the view (in the line <%= link_to 'Show', vendor_product_path(current_vendor, #product) %>. Which view file have you shown, and what is the corresponding controller action?
In that controller action, make sure you add a line to save the product #product.save
In case the #product is valid, then try passing in the fields explicitly:
<%= link_to 'Show', vendor_product_path(:vendor_id => current_vendor.id, :id => #product) %>

No route matches [DELETE]

I don't know what is it happened with my app. I have some controllers that are working perfectly but this one not.
my sylabus_controller.rb
# encoding: utf-8
module Admin
class SylabusController < BaseController
def destroy
#sylabu = #topic.sylabus.find(params[:sylabus])
#sylabu.destroy
redirect_to admin_course_topic_sylabu_path(#course, #topic), notice: 'Sylabus deleted'
end
my /views/admin/sylabus/index.html.rb
<% #sylabu.each do |syla| %>
<tr>
<td><%= syla.mupet_code %></td>
<td><%= syla.name %></td>
<td style="width:155px">
<%= link_to '<i class="icon-pencil"></i>'.html_safe, edit_admin_course_topic_sylabus_path(#course,
#topic,
syla),
class: 'btn' %>
<%= link_to '<i class="icon-trash icon-white"></i>'.html_safe, [:admin, #course, #topic, syla], class: 'btn btn-danger', method: :delete, data: { confirm: 'Are you sure?' } %>
<%= link_to '<i class="icon-eye-open"></i>'.html_safe, [:admin, #course, #topic, syla],
class: 'btn' %>
</td>
</tr>
<% end %>
The target web is in the button delete is localhost:3000/admin/courses/1/topics/2/sylabus.8 and with the following error message
Routing Error
No route matches [DELETE] "/admin/courses/1/topics/2/sylabus.8"
Try running rake routes for more information on available routes.
If I execute rake routes from my console
POST /admin/courses/:course_id/topics/:topic_id/sylabus(.:format) admin/sylabus#create
new_admin_course_topic_sylabu GET /admin/courses/:course_id/topics/:topic_id/sylabus/new(.:format) admin/sylabus#new
edit_admin_course_topic_sylabu GET /admin/courses/:course_id/topics/:topic_id/sylabus/:id/edit(.:format) admin/sylabus#edit
admin_course_topic_sylabu GET /admin/courses/:course_id/topics/:topic_id/sylabus/:id(.:format) admin/sylabus#show
PUT /admin/courses/:course_id/topics/:topic_id/sylabus/:id(.:format) admin/sylabus#update
DELETE /admin/courses/:course_id/topics/:topic_id/sylabus/:id(.:format) admin/sylabus#destroy
Sincerely I don't know from the error is coming because it's a copy and paste from other controllers that are working perfectly.
Well thank you very much for your answers.
Have a great day
By the .8 suffix it looks like it's using the index path instead of the delete path. Try being explicit
<%= link_to 'blah'.html_safe, admin_course_topic_sylabus_path(:admin, #course, #topic, syla), method: :delete %>

Simple ajax rails 3 call troubles

So i'm trying to make a simple ajax call in rails 3 but can't get the ajax to return properly. I think I'm missing something obvious but I've been trying for the past 3 hours so I figured it's time to ask.
I'm attempting the ajax call on the index page of the post model which is supposed to return search results.
My posts_controller.rb for the index action looks like this.
def index
#posts = Post.search(params[:search])
respond_to do |format|
format.html # index.html.erb
format.js #ajax call
format.json { render json: #posts }
end
end
My index.html.erb (which contains the search text field and div where (ajax) results are to be returned looks like this
<%= form_tag posts_path, :method => "get", :remote => true do %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :class => "btn", :name => nil %>
<% end %>
<div id="posts">
<%= render #posts %>
</div>
My _post.html.erb looks like this
<table>
<tr>
<td class="well well-small"><%= post.title %></td>
<td class="well"><%= post.content %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<br />
<br />
</table>
My index.js.erb looks like this
$("#posts").html("<%= escape_javscript(render :partial => "new" ) %>");
and my post.rb model page looks like this
class Post < ActiveRecord::Base
attr_accessible :content, :title
def self.search (search)
if search
find(:all, :conditions => ['title LIKE ?', "%#{search}%"])
else
find(:all)
end
end
end
Sorry there has to be so much code just wanted to show everything relevant. For some reason my search results aren't being updated with ajax. When I remove the :remote => true from the form in index.html.erb and remove the index.js.erb file, the search results are returned fine(without ajax) so my search functionality is not the problem.
Thanks in advance for your help. As always if you give me a good answer, I will accept it as the right one.
The problem is that you're not re-rendering your new collection of posts, you're rendering the 'new' partial!
Try this instead on your index.js.erb file:
$("#posts").html("<%= j(render :collection => #posts ) %>");
Do not change anything else from what you posted and it should work.
If I understand your problem, after your ajax request you want update your view: so I would try something like this in your posts_controller.rb:
format.js do
render :update do |page|
page.replace_html 'id_of_your_refreshed_element', :partial => 'partial_content_refreshed'
end
end
It should work. Your partial_view will take in consideration your new #posts variable.
I hope It will help you.

New instance of a linked model, pass 'caller' id

I'm creating a simple inventory app, there is a view that lists 'items'. It has tables with these rows:
<tr>
<td><%= item.title %></td>
<td><%= item.desc %></td>
<td><%= item.value %></td>
<td><%= item.room.name %></td>
<td><%= item.user.username %></td>
<td>
<%= link_to 'View', item %>
<%= link_to 'Edit', edit_item_path(item) %>
<%= link_to 'Delete', item, method: :delete, data: { confirm: 'Are you sure?' } %>
<%= link_to 'Add Comment', !?????! %>
</td>
/tr>
I have a linked model for 'comments' set up but don't know how to pass the 'item_id' to it when creating a new one.
The URL helpers actually accept the object to make a route for an association. Meaning, assuming you have a nested route for comments within items,
resources :items do
resources :comments
end
you can link_to the new_item_comments_path(item).
The method new_item_comments_path(item) makes a string URL based on the new_item_comments route, which you feed to link_to to make an HTML <a> tag.
To be clearer, in your view you would have:
<%= link_to 'View', item %>
<%= link_to 'Edit', edit_item_path(item) %>
<%= link_to 'Delete', item, method: :delete, data: { confirm: 'Are you sure?' } %>
<%= link_to 'Add Comment', new_item_comments_path(item) #-> (instead of ???) %>
In this case, the item you are passing is the reference to your current item, which allows the URL helper to make a URL for it from the route.
The Rails guide for routing should be a useful read for you.
Now that's assuming your Comment controller assigns the right stuff at the right place. You seemed to have figured that out, but I'll explain for the sake of clarity (and future visitors)
class CommentsController < ApplicationController
# GET /item/:item_id/comments/new
def new
#comment = Comment.new
#item = Item.find(params[:item_id])
#comment.item = #item
# render
end
# POST /item/:item_id/comments
def create
#comment = Comment.new(params[:comment])
#item = Item.find(params[:item_id])
#comment.item = #item
# if #comment.save blah
end
end
All credit should go to #jonallard
The solution is all about routing it seems, you need to pass a url to the form that makes new comments (linked models).
to do this:
Add this (or similar depending on object names) to the page that is calling the creation:
<%= link_to 'Add Comment', new_item_comment_path(#item) %>
In both the new and the create method of the comments_controller there is a line starting #comment = Comment.new. Under that line add:
#item = Item.find(params[:item_id]) AND
#comment.item = #item
edit the top line of the comments template for to: <%= form_for(#comment, {:url => item_comments_path(#item)}) do |f| %>
Edit routes to somethings like:
resources :items do
...
resources :comments
end
and Read this: http://guides.rubyonrails.org/routing.html#creating-paths-and-urls-from-objects!
As mentioned before all credit goes to #jonallard, his answer and his expertise.

How to create custom method in Rails?

I'm currently trying to use a custom method in Rails and I do not know how to do so. Apart from the default methods in the controller, I wanted to add the following:
def cancel
#newsletter = Newsletter.find(params[:id])
respond_to do |format|
#SendGrid Newsletter API - Delete Newsletter Schedule
SendGrid.delete_schedule(#newsletter.name)
#newsletter.status = "CANCELLED"
#newsletter.save
format.html { redirect_to newsletters_url }
format.json { head :no_content }
end
end
The method is just like the default :destroy method but it doesn't actually destroys the object.
In my view, I had the following:
<% #newsletters.each do |newsletter| %>
<tr>
<td><%= newsletter.identity %></td>
<td><%= newsletter.name %></td>
<td><%= newsletter.recipients %></td>
<td><%= newsletter.subject %></td>
<td><%= newsletter.html %></td>
<td><%= newsletter.text %></td>
<td><%= newsletter.schedule %></td>
<td><%= newsletter.status %></td>
<td><%= link_to 'Show', newsletter %></td>
<td><%= link_to 'Edit', edit_newsletter_path(newsletter) %></td>
<td><%= link_to 'Destroy', newsletter, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<td><% if newsletter.status == "SCHEDULED" %><%= link_to 'Cancel', newsletter, method: :cancel, data: { confirm: 'Cancel Schedule?' }%><% end %></td>
</tr>
<% end %>
I got the error: No route matches [POST] "_newsletter url__"
When I rake routes, there isn't any route for the error above. May I know how to add the route and why is the route needed?
UPDATE
Currently, I still have the no route matches error. Below are all my files related to the 'Cancel' method:
routes.rb
resources :newsletters do
match '/cancel/:id' => 'newsletters#cancel', :as => :cancel
end
newsletters_controller.rb
def cancel
#newsletter = Newsletter.find(params[:id])
respond_to do |format|
#SendGrid Newsletter API - Delete Newsletter Schedule
SendGrid.delete_schedule(#newsletter.name)
#newsletter.status = "CANCELLED"
#newsletter.save
format.html { redirect_to newsletters_path(#newsletter) }
format.json { head :no_content }
end
end
newsletters/index.html.erb
<%= link_to 'Cancel', newsletter_cancel_path(newsletter) %>
You should have a line like this in your config/routes.rb file
resources :newsletters
You'll want to change it to this
resources :newsletters do
member do
put 'cancel'
end
end
You'll want to take a look at the routing guide that Иван Бишевац posted. You'll also want to understand basic restful routing and how Rails handles GET, POST, PUT, DELETE, etc.
I think you're mistaking the method: argument in the link_to as corresponding to the method in the controller. Actually it is referring to the RESTful HTTP verb i.e. :post, :delete and :put. So you don't pass the controller action through this way.
Instead you can pass in :controller and :action arguments...
Better still create a route in routes.rb and use the path that rails generates.
match "/cancel/:id", to: "controller#cancel", as: :cancel
and then the link_to would be something like:
link_to 'Cancel', cancel_path(newsletter)
Update:
The error you're getting is with the redirect_to in your cancel method (in the controller). Change the newsletters_url to newsletter_path(#newsletter) instead.
If you want to redirect back to the show page for a single newsletter, then you need to do the above (where you pass in the #newsletter parameter), if you want it to go back to the newsletters index page then it'll be newsletters_path.
You can check the existence of the routes by typing rake routes in your terminal. You'll see all the route names there.
Do you still get an error after changing to redirect_to newsletter_path(#newsletter)?
The thing that doesn't quite strike true is that you're getting a no POST route defined - which usually points to a malformed form_for. Examine your newsletter related forms especially any where you don't do the regular form_for #newsletter do |f|.
Here is complete explanation about routing:
http://guides.rubyonrails.org/routing.html

Resources