I am facing a weird problem
when I am trying to destroy active record it is giving this error.
AbstractController::ActionNotFound at /photos/6
The action 'destroy' could not be found for PhotosController
here is what my controller look like
class PhotosController < ApplicationController
before_filter :authenticate_user!
....
....
def delete
#photo = current_user.photos.find(params[:id])
#photo.destroy
redirect_to photos_path
end
and if I perform the same actions using console it is working fine(the record is getting deleted successfully ).
This is my routes file look like.
resources :photos, :only => [:index, :show, :new, :create] do
post 'upload', :on => :collection
end
I know I have not included :destroy in resources please suggest me how to insert :destroy action to delete photos
if you have resource of photo then action name should be destroy, not delete. and if not then please check your routes.
Seven default action that are generated by scaffolding are follow
index
new
edit
create
update
show
destroy # not delete
I am assuming you are using resources :photo.
The action should be destroy and not delete, as per the Rais Guide.
The seven default actions are: index, new, create, show, edit, update and destroy
def destroy
#photo = current_user.photos.find(params[:id])
#photo.destroy
redirect_to photos_path
end
You can also see the available routes by:
rake routes
EDIT
The problem is here: :only => [:index, :show, :new, :create], which is saying to rails: do not create destroy, edit or update routes.
To solve the problem, you can add destroy to it :only => [:index, :show, :new, :create, :destroy] or use :except instead: :except => [:edit, :update]
If you don't want to limitate the resources:
resources :photos do
post 'upload', :on => :collection
end
EDIT 2 - I don't really understand why you are trying to use delete instead of destroy, However, if you have a good reason for it:
resources :photos :only => [:index, :show, :new, :create] do
post 'upload', :on => :collection
get 'delete', :on => :member
end
In this way you will have the delete_photo_path, which can be used in your show view:
<%= link_to 'Delete', delete_photo_path(#photo) %>
Finally, the action delete should looks like:
def delete
#photo = Photo.find(params[:id])
#photo.destroy
redirect_to photos_path
end
Related
I am trying to create a log out for my app and in my controller this piece of code is not working. Any solution would be helpful.
def destroy
#user = user.find(params[:id])
#user.destroy
end
This is my destroy method in my sessions controller(the fact that i am destroying my user in my sessions controller might be the problem)
class UsersController < ApplicationController
def new
end
def create
#user = User.create(password: params[:password],
email: params[:email],
firstname: params[:firstname],
lastname: params[:lastname])
redirect_to user_path(#user)
end
def show
#user = User.find(params[:id])
end
end
routes.rb:
Rails.application.routes.draw do
# Fubyonrails.org/routing.html
root :to => 'static#welcome'
resources :users, only: [:new, :create, :show]
resources :session, :only => [:new, :create, :destroy]
resources :studios
end
Routes file
uninitialized constant SessionController
is the error im getting
First, don't destroy your user. It deletes it from the database, you want them to be able to login again without creating a new user right?
You need to update your routes.rb file to be:
Rails.application.routes.draw do
# Fubyonrails.org/routing.html
root :to => 'static#welcome'
resources :users, only: [:new, :create, :show]
resources :sessions, :only => [:new, :create, :destroy] # changed to sessions
resources :studios
get 'logout' => 'sessions#destroy'
end
If you don't already, you need to define a SessionsController.
class SessionsController < ApplicationController
def destroy
# insert logic that actually logs them out, the below may already be enough
# for this purpose though
redirect_to root_url, notice: "Logged Out Successfully"
end
end
When the user clicks "Logout" it gets routed to the SessionsController#destroy action which redirects them to the root URL ('static#welcome')
There is more to it then that (i.e. the views and all that jazz) but this should be helpful enough
I'm trying to use the link_to helper function to create a new order for a particular product. Here is my:
product model
class Product < ActiveRecord::Base
has_many :orders
end
routes.rb
resources :products, :only => [:show, :new, :create, :index, :update, :destroy] do
resources :orders, :only => [:create]
end
view for product/show.html.erb
<%= link_to 'New Order', new_product_orders_path(#product) %>
controller for orders
class OrdersController < ApplicationController
def create
#order = Order.new
end
end
relevant rake routes:
product_orders POST /products/:product_id/orders(.:format) orders#create
But when I do that I get undefined method `new_product_orders_path'
Whats the correct way to do this in Rails 4?
In your routes add new action here
resources :orders, :only => [:create, :new]
Also your controller is missing new action, in your create action you need to save your record
class OrdersController < ApplicationController
before_filter :set_product
def new
#order = #product.orders.new
end
def create
#order = #product.orders.new(params[:order])
#order.save
end
private
def set_product
#product = Product.where("id =?", params[:product_id]).first
end
end
I think you need
resources :products, :only => [:show, :new, :create, :index, :update, :destroy] do
resources :orders, :only => [:create, :new]
end
You can also check your routes by typing '/rails/info/routes' at the end of your server path.
In Rails, when I need:
/comments
and
/posts/1/comments
How do I best organize CommentsController? E.g. let the routes share the index actions, or work with 2 controllers?
You can work with only one controller.
I would go with a before_filter to check if the post_id param is present:
class CommentsController < ApplicationController
before_filter :find_post, only: [:index]
def index
if #post.present?
## Some stuff
else
## Other stuff
end
end
private
def find_post
#post = Post.find(params[:post_id]) unless params[:post_id].nil?
end
end
And have in your routes (with the constraints of your choice) :
resources :posts do
resources :comments
end
resources :comments
I believe you want /comments only for show and index actions, right? Otherwise the post params will be lost when creating or updating a comment.
In your routes.rb you can have something like:
resources : posts do
resources :comments
end
resources :comments, :only => [:index, :show]
In your form:
form_for([#post, #comment]) do |f|
And in your controller, make sure you find the post before dealing with the comments (for new, edit, create and update, such as:
#post = Post.find(params[:post_id])
#comment = #post...
You can do almost anything you want with rails routes.
routes.rb
match 'posts/:id/comments', :controller => 'posts', :action => 'comments'}
resources :posts do
member do
get "comments"
end
end
(I'm french)
I've a problem with my Rails (3.2.11) application. When i set my routes with some nouns, it doesn't work !
I explain:
Way::Application.routes.draw do
scope(:path_names => { :new => "nouveau", :edit => "edition" }) do
scope "/admin" do
resources :news, except: [:show, :index], path: '/articles'
resources :users, except: [:show]
resources :pages, except: [:show]
resources :events, except: [:show, :index]
resources :projects, except: [:show,:index], path: '/projets'
resources :galleries, except: [:index, :show] do
resources :paintings, except: [:index, :show]
end
end
end
end
The resources :projects doesn't work when i set it to "/projets".
What doesn't work is: when i want to create a new project in my form, i click on submit, it simply redirect me to "/projets", without doing something !
But when i set the route to "/poneys" for example, it works ! I really don't understand.
Thanks for your help.
https://github.com/khcr/way
class ProjectsController < ApplicationController
def new
#project = Project.new
render layout: 'admin'
end
def create
#project = Project.new(params[:project])
if #project.save
flash[:success] = "Projet créé"
redirect_to project_path(#project)
else
render 'new', layout: 'admin'
end
end
end
I'm in a sort of weird situation where I'm getting a strange error with nested resources.
I have a nested resource defined as below:
resources :users do
resources :comments, :only => [:create, :destroy]
end
My end point for comments is json only so its controller is defined as follows. Take note that I am using cancan and actsAsApi gems.
class CommentsController < ApplicationController
load_and_authorize_resource
self.responder = ActsAsApi::Responder
respond_to :json
# POST /comments.json
def create
flash[:notice] = 'Comment was successfully created.' if #comment.save
respond_with(#comment, :api_template => :default)
end
# DELETE /comments/1.json
def destroy
#comment.destroy
respond_with(#comment, :api_template => :default)
end
I can then send a post request to '/users/1/comments.json' with some request parameters and the comment will get created like expected. Unfortunately I am getting an error where it tries to locate the destroy action:
Completed 404 Not Found in 169ms
ActionController::RoutingError (No route matches {:action=>"destroy", :controller=>"comments", :id=>#<Comment id: 34, user_id: 1, text: "test test test", created_at: "2012-02-28 06:45:49", updated_at: "2012-02-28 06:45:49">}):
app/controllers/comments_controller.rb:12:in `create'
As extra information, if I modify routes.rb to this:
resources :comments, :only => [:destroy]
resources :users do
resources :comments, :only => [:create]
end
I don't see any error.
Because you are using nested resources you need to tell cancan to load both the users and the comments for actions on comments to work.
See as follows:
class CommentsController < ApplicationController
load_and_authorize_resource :user
load_and_authorize_resource :comment, :through => :user
end
See more details on the cancan nested resource page
I have been able to figure this out. Basically it is required that when you nest resources you use respond_with as follows:
respond_with(#comment.note, #comment, :api_template => :default)