If I generate a scaffold I get the standard actions index, new, show, create .... all of which contain a line e.g. like
#comment = Comment.find(params[:id])
Does it make sense to put this line in a seperate method into the controller like
def load
#comment = Comment.find(params[:id])
end
Is this an advantage? Thx for your time
Yes to the separate method, and also yes to using a before_filter.
class CommentsController < ApplicationController
# Whitelist your before_filter like this. Or you can blacklist it with :except => []
before_filter :load_comment, :only => [:edit, :update, :destroy, :show]
def show
end
def index
#comments = Comment.all
end
def new
#comment = Comment.new
end
# etc ...
protected
def load_comment
#comment = Comment.find(params[:id])
end
end
Related
In the comments controller, I am redirecting to the articles show page after both create and destroy.
So I decided to write an after_action which would do the redirect_to.
class CommentsController < ApplicationController
before_action :find_article
before_action :find_comment, only: [:destroy]
after_action :goto_articles_page, only: [:create, :destroy]
def create
#comment = #article.comments.create(comment_params)
end
def destroy
#comment.destroy
end
private
def comment_params
params.require(:comment).permit(:commenter, :body)
end
def find_article
#article = Article.find(params[:article_id])
end
def find_comment
#comment = #article.comments.find(params[:id])
end
def goto_articles_page
redirect_to article_path(#article) and return
end
end
But this gives me AbstractController::DoubleRenderError after both create and destroy.
Why am I getting this error?
By default, Rails will render views that correspond to the controller action. See Rails Guides.
So in your create and destroy actions, Rails is performing a render by default. Then your after_action (which happens after the action) is redirecting, so it's double rendering.
Instead of an after_action, you could call the goto_articles_page method in your controller actions.
For example:
def destroy
#comment.destroy
goto_articles_page
end
def goto_articles_page
redirect_to article_path(#article) #return not needed
end
I think using return when rendering any action but when redirect_to use then not need to use return then finally you can remove and return
Rails guide very nicely explained that you can follow this carefully
redirect_to explanation
Hope to help
How to set a before_action method with dynamic params, I keep getting an error wrong number of arguments (0 for 1)
class PagesController < ApplicationController
before_action :set_categories
before_action :redirect_if_path_has_changed, only: [:products, :detail]
def home
end
def products
#category = Category.find(params[:id])
#products = #category.products.order("created_at").page(params[:page]).per(6)
redirect_if_path_has_changed(products_by_category_path(#category))
end
def detail
#product = Product.find(params[:id])
redirect_if_path_has_changed(product_details_path(#product))
end
private
def set_categories
#categories = Category.all
end
def redirect_if_path_has_changed(path_requested)
redirect_to path_requested, status: :moved_permanently if request.path != path_requested
end
end
Thank you before
You can do it like this:
before_action only: [:products, :detail] do
redirect_if_path_has_changed("value")
end
Try this. The above works when you need to set any value or something before the action. In you case you want to first find the product or detail from database then you want to redirect to that path. So before_action just calls before the two actions which is not useful in your case.
The error appears when I try to submit a comment. - ActiveRecord::RecordNotFound in CommentsController#index - I followed this and this tutorial
the URL is:
.../articles/1/comments
comments_controller
class CommentsController < ApplicationController
before_action :set_comment
before_action :signed_in_user, only: [:new]
def index
#commentable = load_commentable
#comments = #commentable.comments
end
...
def create
#comment = #commentable.comments.new(comment_params)
#comment.user = current_user
if #comment.save
redirect_to #comment, notice: "Comment created."
else
render :new
end
end
....
private
def load_commentable
resource, id = request.path.split('/')[1, 2]
#commentable = resource.singularize.classify.constantize.find(id)
end
def set_comment
#comment = Comment.find(params[:id])
end
....
Full trace:
As per the stacktrace, error is appearing on set_comment method.
You must be having a callback before_action on set_comment which should not be there for index action. You should restrict that to only relevant actions.
For example:
before_action :set_comment, only: [:show, :edit, :update, :destroy]
So that this callback would only be invoked for show, edit, update and destroy actions.
UPDATE
Currently callback is set as before_action :set_comment without any restrictions so it will be invoked before each and every action. So, update it as suggested above.
class FrogsController < ApplicationController
before_action :find_frog, only: [:edit, :update, :show, :destroy]
after_action :redirect_home, only: [:update, :create, :destroy]
def index
#frogs = Frog.all
end
def new
#ponds = Pond.all
#frog = Frog.new
end
def create
#frog = Frog.create(frog_params)
end
def edit
#ponds = Pond.all
end
def update
#frog.update_attributes(frog_params)
end
def show
end
def destroy
#frog.destroy
end
private
def find_frog
#frog = Frog.find(params[:id])
end
def frog_params
params.require(:frog).permit(:name, :color, :pond_id)
end
def redirect_home
redirect_to frogs_path
end
end
Hi all. I was wondering if someone could explain to me why the update route in rails can't take my after_action of redirecting (custom made method on the bottom) it home. The error that I get when i include update in the after_action is "Missing template frogs/update".
This is going to cause me to manually add a redirect_to frogs_path inside the update method.
thanks!
The after_action callback is triggered after the action has run its course. You cannot use it to render or redirect. Do that within the action itself by calling the method:
def update
...
redirect_home
end
For some reason, I keep getting this error.
Couldn't find Album without an ID
But that doesn't make sense because in my debug.params it says:
{"utf8"=>"✓",
"authenticity_token"=>"os9DVVZS6//bs3Ne2Xfrh4VnKXNtDXkZaE4s/3iQagE=",
"video"=>{"url"=>"www.youtube.com/watch?v=yIRuri1AB0I",
"album_id"=>"1"},
"commit"=>"Next"}
Here is the controller:
class VideosController < ApplicationController
include AlbumsHelper
before_filter :signed_in_user, only: [:create, :destroy] #add update later
before_filter :correct_user, only: :destroy
def show
#video = Video.find(params[:id])
end
def new
if signed_in?
#album = Album.find(params[:album_id])
#video = #album.build_video
end
end
def create
#album = Album.find(params[:album_id])
#video = #album.build_video(params[:video])
if #video.save
flash[:success] = "Success!"
redirect_to new_small_reward_path(:album_id => #album)
else
render 'new'
end
end
end
I even added a hidden field to the form, which I didn't think I should have to do, but decided to try:
The URL says /videos/new?album_id=1 before you click submit.
This problem completely goes away if I write the controller with this:
def new
##album = Album.find(params[:album_id])
end
and then continue to use the class variable throughout the entire thing. But someone told me that using a class variable is discouraged. How do I do this correctly?
#album = Album.find(params[:video][:album_id])