1

I have several controllers (lets say one is the PostsController) that all inherit from the AuthenticatedController. Many methods in each of these child controllers perform similar CRUD actions and redirect back to the request referer,

I wanted to DRY up my controllers, so I refactored that code and put it all in a single method in the AuthenticatedController called do_action that will accept the object, action, and flash message.

class AuthenticatedController < ApplicationController

    private

    def do_action(action, obj, message, anchor='')
        if obj.try(:action)
            flash[:notice] = message
        else
            flash[:error] = 'Error Occurred'
        end
        redirect_to request.referer + anchor
    end 

end

class PostController < AuthenticatedController 

    def create
        @post = Post.new
        do_action(:save, @post, 'Created Successfully', "#post-#{@post.id}")
    end

end

It works great, except that flash messages do not appear in my view anymore.

If I move do_action back into the PostsController, the flash messages appear as expected:

class PostController < AuthenticatedController 

    def create
        @post = Post.new
        do_action(:save, @post, 'Created Successfully', "#post-#{@post.id}")
    end

    private

    def do_action(action, obj, message, anchor='')
        if obj.try(:action)
            flash[:notice] = message
        else
            flash[:error] = 'Error Occurred'
        end
        redirect_to request.referer + anchor
    end

end

From what I understand after reading this SO question, flash is a method delegated to the request object. I'm able to access the request object in AuthenticatedController, I think request.referer?

Why can't I assign a message to flash from a method in AuthenticatedController?

Community
  • 1
  • 1
chester
  • 297
  • 2
  • 13
  • You prolly shouldn't do it this way. I think the issue is using request.referer, maybe request.base_url would be better. – trueinViso Jan 27 '17 at 00:36

1 Answers1

1

firstly, i don't think that DRY is the way to go here. you should do it "the rails way". that is to be a bit repetitive and have those if @post.save stuff in all the actions. it does not hurt, really, you will get over it.

secondly, something else is wrong, flash has to work no matter where it's in. it's more likely that your abstraction introduced some bug. use a debugger to find out what is going on.

phoet
  • 18,688
  • 4
  • 46
  • 74
  • Thanks, you were right .. something else was wrong, which may have just been the lack of my server being restarted. It is working as expected now. – chester Jan 27 '17 at 21:03
  • As far as "the rails way," there aren't any downstream rails conventions that depend on what otherwise would have been the pattern I abstracted, are there? I know the idea is to use conventions so that I (or someone else) doesn't have to re-learn how the code is organized. But in this case, it saves me from having to update 7 or 8 different controllers when I want to add a small bit of logic, like redirecting with an anchor. – chester Jan 27 '17 at 21:13
  • you only learn from your own mistakes. if you think that having this makes your code better, there is nothing stopping you in my opinion. just keep in mind that DRY comes at the very least of measures to apply to code. think twice before introducing abstractions. – phoet Jan 28 '17 at 19:09