Reputation: 115
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
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
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
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