It seems select method is overrided inside Parts. MWE : (context is Hanami 2.2)
# app/views/posts/index.rb
module MyApp
module Views
module Posts
class Index < MyApp::View
expose :posts do
(1..9)
end
expose :filtered_posts do |posts|
posts.select(&:even?)
end
end
end
end
end
# app/views/parts/posts.rb
module MyApp
module Views
module Parts
class Posts < MyApp::Views::Part
def even_filter
select(&:even?) # this leads to "wrong number of arguments (given 0, expected 1..4)" error
end
def working_even_filter
find_all(&:even?) # this works !
end
end
end
end
end
I get a syntax error wrong number of arguments (given 0, expected 1..4) pointing the select line.
Replacing select(&:even?) by find_all(&:even?) leads to expected behavior. Note that inside view, select works as expected (see filtered_posts).
What the purpose of overrided select method inside parts ?
I think this is because HTML tag helpers are included in the part by default and it interprets it as an attempt to render an HTML select tag. Which is indeed unfortunate.
I thought tag helpers were accessible with helpers.tag not directly as is. So select tag would require helpers.tag.select .... Actually, (inside a Parts method)
I think this is because Kernel#select is being called.
Part classes decorate your value object, and forward methods to the value via #method_missing. But because Kernel#select exists, the method isn’t missing, and therefore the value’s method is not being called.
Interestingly, after years of doing it this way (via dry-view before hanami-view), you’re the first person to hit this! Thank you for sharing!
I think this warrants a re-look at how we delegate methods from the part to the value, but for the time being, at least you should now be able to handle these more confidently in the future: if a same-named instance method already exists on Object, you’ll need to be more explicit in calling the value itself.
Thanks for replying and pointing out which object is hitted by select inside Parts.
My mistake : thinking that part “decorates” exposures by a kind of exposure.extend( Part ) mechanism. So I expected Enumerable methods still available when exposure is a collection… I will take care on that.
Perhaps Hanami Parts are not designed this way on purpose. Perhaps the Hanami way is to do this selection job inside views… Does Hanami team provide a ‘best practice’ in this area ?