EDIT:
I got many responses with different approaches for solving the problem, thanks a lot!
Sadly, none of them worked until now.
To easily understand and reproduce the failure, I created a small Rails repo on GitHub with a Rspec suite.
One of the specs is passing (where the presenter is initialized in the view). One of the specs is failing (where the presenter is initialized in the controller).
How make them both pass ?
ORIGINAL QUESTION BELOW:
This is my Presenter:
class UserPresenter
def initialize(user, vc)
@user = user
@vc = vc
end
def linkify()
#
# HERE IS THE PROBLEM
#
vc.link_to("foo") do
yield
end
end
end
This is my Controller:
I initialize my Presenter in the controller, passing the view context of the controller with the presented model.
class UserController
def show
@user = User.find(#.....
@presenter = UserPresenter.new(@user, view_context)
end
end
In my Slim template, I call my Presenter to put the content in a link:
=@presenter.linkify do
p "123"
My problem is, I can't pass the block from the view to my linkify
method.
In the with comment marked above code, the passed block is the whole view content, instead of the p 123
.
When I initialize my Presenter in the view via: @presenter = UserPresenter.new(@user, self)
, it works as expected.
How I can make the linkify method uses the provided block, without initializing the presenter in the view ?
Because if you are going to use the yield command, you mustn't specify the &block, since now you are effectively receiving a block as a parameter using normal parameter syntax.
class UserPresenter
def initialize(user, vc)
@user = user
@vc = vc
end
def linkify() # <-- Remove &block
vc.link_to("foo") do
yield
end
end
end
# ...
# Somewhere else, assuming you have access to @presenter which is an instance of
# UserPresenter
# ...
def show
@presenter.linkify do
# ...
# do my view stuff here
# ...
end
end
show()
# Now, if your "View" is nothing but a block that needs to get passed in
# then you'd do this...
def show(&block)
@presenter.linkify do
block.call()
end
end
# This would be used this way:
show(lambda {
# ...
# View stuff here
# ..
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With