Anton
Anton

Reputation: 115

Naming conventions for custom dir under /app/ in a Rails app?

I have question about naming conventions and autoloading.

I want to have a presenter ItemPresenter in app/presenters/items/item_presenter.rb

My understanding was that I can just create that file like this:

module Items
  class ItemPresenter
  end
end

But when I do this and try to call the presenter as Items::ItemPresenter I get uninitialized constant error:

uninitialized constant Items::ItemPresenter

def show
   @presenter = Items::ItemPresenter.new # this is the highlighted line of my Controller

EDIT: Rails, Custom Folders and Namespaces is not duplicate because it's about different dir structure jobs/smth.rb while I am trying to implement presenters/items/item_presenter.rb (1 more level)

EDIT2: neither it works from rails console: NameError: uninitialized constant Items::ItemPresenter

EDIT2: I tried doing this as suggested:

module Presenters
  module Items
    class ItemPresenter
      def test
        "hello"
      end
    end
  end
end

And @presenter = Presenters::Items::ItemPresenter.new in my controller:

 uninitialized constant TrialsController::Presenters

It seems like Rails do not see that directory at all.

EDIT3: Created a sample app https://github.com/dontlookforme/test_app

EDIT4: Figured it out. I screwed up the file name (see the answer I've posted)

Upvotes: 0

Views: 413

Answers (3)

Anton
Anton

Reputation: 115

Ugh. The thing I was doing wrong is the file name. I named the preseter file items_presenter.rb but the class had singular Item in the name ItemPresenter.

Fixed that and everything started working.

Thanks for the help guys!

Upvotes: 0

sixty4bit
sixty4bit

Reputation: 7956

I found the answer but it's necessary to see @user1556912's sample app (link in the original question) to see what happened.

The problem is that the filename is items_presenter.rb (plural) but the class name is ItemPresenter (singular).

As I pointed out in a comment on @Anthony E's answer, Rails will autoload everything in the /app dir, so it's not necessary explicitly to tell Rails about these files. However, along with namespaces matching dir hierarchies, the names of the classes must also match the names of the files exactly. In this case, I was able to get the class to load in the rails console by renaming items_presenter.rb to item_presenter.rb.

Going back to @Anthony E's answer, though, I do agree that the Items:: namespace seems superfluous here. I would just do app/presenters/item_presenter.rb.

Upvotes: 1

Anthony E
Anthony E

Reputation: 11235

app/presenters/ is the conventional path to store presenters. In fact, you can probably go without folder nesting for items:

app/presenters/item_presenter.rb

You'll need to update the module path accordingly:

  module Presenters
    class ItemPresenter
      def test
        "hello"
      end
    end
  end

Then, you can tell Rails to automatically load this file in your application.rb:

config.autoload_paths << '#{config.root}/app/presenters'

Upvotes: 0

Related Questions