Rails shared helpers within views conflict

87 views
Skip to first unread message

Rodrigo Lueneberg

unread,
Feb 5, 2014, 11:46:12 AM2/5/14
to rubyonra...@googlegroups.com
According to this article Rails helpers from all controllers are
available to all views. But to me this looks kind of a dangerous
approach because I might at some point use helper methods with the same
name but with different implementations that can cause conflicts and
undesired results. This actually happened one time and it took me quite
some time to figure out the problem.

Why is the Rails helper scope this way?
What is the reason for sharing?
Does anyone had any problems with this approach?
Is there another recommended way to work?

http://strugglingwithruby.blogspot.com.br/2008/10/view-part-2-scope-helpers-and-partials.html

Thank you

Rod

--
Posted via http://www.ruby-forum.com/.

Frederick Cheung

unread,
Feb 5, 2014, 12:14:26 PM2/5/14
to rubyonra...@googlegroups.com
The reason is to encourage people to split out their helpers rather than just dumping everything in application_helper.rb (because with this you can do that without having to add lots of helper :blah lines to your controllers). Personally I think it's a really bad idea for the reason you mention and always set config.action_controller.include_all_helpers = false to stop this happening

It's also worth looking at gems just as draper - a lot of the helpers I used to write secretly wanted to be decorators

Fred
 

Rodrigo Lueneberg

unread,
Feb 5, 2014, 2:29:41 PM2/5/14
to rubyonra...@googlegroups.com
Frederick,

Thanks. I am glad you agree with me. By the way, do you recommend
setting this option to false as good practice on every fresh project?
Looks like your idea solves the issue, but of course, will force you to
dump stuff like you said, in application.rb.

I researched a little bit and I found a way to reference common code in
application without bloating it out making you suggestion a good
practice.

For instance, instead of placing Currency code in application code you
just reference it with an include and it will be available in all views.
This is better approach than the promiscuous helper architecture

module ApplicationHelper
include CurrencyModule

def blabla
end

Is there any other reason for not doing this:
config.action_controller.include_all_helpers =
false?

end

thanks

Frederick Cheung wrote in post #1135687:

Frederick Cheung

unread,
Feb 5, 2014, 4:47:11 PM2/5/14
to rubyonra...@googlegroups.com


On Wednesday, February 5, 2014 7:29:41 PM UTC, Ruby-Forum.com User wrote:
Frederick,

Thanks. I am glad you agree with me. By the way, do you recommend
setting this option to false as good practice on every fresh project?
Looks like your idea solves the issue, but of course, will force you to
dump stuff like you said, in application.rb.

 
I always do. It doesn't force you to dump stuff in application_helper.rb, it just makes that the path of least resistance.
 
I researched a little bit and I found a way to reference common code in
application without bloating it out making you suggestion a good
practice.

For instance, instead of placing Currency code in application code you
just reference it with an include and it will be available in all views.
This is better approach than the promiscuous helper architecture

module ApplicationHelper
  include CurrencyModule

def blabla
end


Personally I'd rather write 

helper :currency

in application controller (or whatever is the appropriate subset of controllers). 

Fred

Rodrigo Lueneberg

unread,
Feb 5, 2014, 7:58:35 PM2/5/14
to rubyonra...@googlegroups.com
Frederick

Could you please elaborate "helper :currency?" Can you give an example?

Thanks
Rod

Frederick Cheung wrote in post #1135734:
> On Wednesday, February 5, 2014 7:29:41 PM UTC, Ruby-Forum.com User
> wrote:
>>
>> Frederick,
>>
>> Thanks. I am glad you agree with me. By the way, do you recommend
>> setting this option to false as good practice on every fresh project?
>> Looks like your idea solves the issue, but of course, will force you to
>> dump stuff like you said, in application.rb.
>>
>>
> I always do. It doesn't force you to dump stuff in
> application_helper.rb,
> it just makes that the path of least resistance.
>
>
>>
>> def blabla
>> end
>>
>>
> Personally I'd rather write
>
> helper :currency
>
> in application controller (or whatever is the appropriate subset of
> controllers).
>
> Fred

Frederick Cheung

unread,
Feb 6, 2014, 6:37:03 AM2/6/14
to rubyonra...@googlegroups.com


On Thursday, February 6, 2014 12:58:35 AM UTC, Ruby-Forum.com User wrote:
Frederick

Could you please elaborate "helper :currency?" Can you give an example?


class FooController < ApplicationController
  helper :currency # <- CurrencyHelper module is included in views rendered by this controller
end
 
Fred

Rodrigo Lueneberg

unread,
Feb 6, 2014, 1:16:33 PM2/6/14
to rubyonra...@googlegroups.com
I got it. There is also another way, which is to define the helper
method as an instance of the helper class using "self". This way:

def self.format_currency(price)
...
end

Then in the view this this <%=
Admin::currencyHelper.format_currency(price)%>

But the drawback is that you have to manually use the full namespace in
your views and the code might get ugly. But, I know it is bad but it is
an option.

I kind of like you last suggestion, and I wish I had learned this trick
before. Just to clarify your last suggestion, in the case of the
Currency, do you create a stand-alone helper, I mean, a helper separated
from a controller and place it into the helpers folder?

Thank you

Matt Jones

unread,
Feb 6, 2014, 2:08:07 PM2/6/14
to rubyonra...@googlegroups.com
Depends on who you ask - I'm of the opinion that if you have two functions with the same name but mixed into different controllers you've just made your code harder to navigate. At that point, the result of rendering a template is dependent on which controller is rendering it (since the controller picks which helpers are available).

--Matt Jones 

and...@benjamin.dk

unread,
Feb 8, 2014, 9:16:23 AM2/8/14
to rubyonra...@googlegroups.com
There is 2 more things about helpers:

- First your helpers should be something really small, if you need too many functions, your doing something wrong, either you need to pass something to the models or build decorators.

- Another thing is: can you give me an example of a helper you need to set the same name for? I mean is that gonna happen that often?

Rodrigo Lueneberg

unread,
Feb 8, 2014, 1:24:03 PM2/8/14
to rubyonra...@googlegroups.com
There it goes the example. Sorry, I did not know how to format.

def self.get_order_assets(od_id)
return OrderAsset.select("assets.file_name,
order_assets.*").joins("INNER JOIN assets ON assets.id =
order_assets.asset_id ").where("order_detail_id=#{od_id}")
end

def get_order_assets(od_id)
oa =OrderAsset.select("order_assets.*").where("order_detail_id =
#{od_id}")
return oa
end

and...@benjamin.dk

unread,
Feb 8, 2014, 3:22:46 PM2/8/14
to rubyonra...@googlegroups.com
Is this 2 methods inside of which files?

To start I dont see the point of the select here:

oa =OrderAsset.select("order_assets.*").where("order_detail_id = 
   #{od_id}") 

this is the same as 

oa =OrderAsset.where("order_detail_id = 
   #{od_id}") 

Second thing, you should use a scope for this on the model!

Third:

The way you should call them are completly wrong! one returns a collection of assets the other one returns an asset.

I also dont understand why you are defining class methods for an helper(maybe you have a good reason).

So the first one that returns a collection you should actually giving a name to it like:
(you should use scopes again but now I just wanna give you a naming example)

def get_order_assets_from_detail

and the other one:

def get_order_asset_from_detail

you see the difference on the s?

I hope you understand what I mean, but I think you need to look more into scopes and how to create decorators! It will give you an insight of what you should put in a decorator, a model and in a helper!

all the best,

Andre
Reply all
Reply to author
Forward
0 new messages