I'm having some trouble realising how the helper methods should be used in views. For example, take these parts of code:
Mycontrollers_helper.rb
module MycontrollersHelper
def destroy_everything
Model.destroy_all
redirect_to root_path
end
end
How should it be used in the view then ? Let's say adding the method to a button in the view:
<%= button_to 'Destroy all', destroy_everything, method => :post %>
Is just writing a method in the helper.rb file enough or does it require some additional lines in the controller it refers to ? Is this even the correct syntax for something like this ?
Helpers in rails actually view helpers. So they are meant to provide some help to render your views.
If you want to delete something, and then redirect to some action, just use a controller action for that.
I think you are taking about view helper, which you want to call from your view template.
You can call your view helper with the name of the method.
Calling destroy_everything will works fine if this helper is included in your controller.
Update:
If you write your helper method in application helper then you don't need to worry about load/ include the helper.
Related
Lets say I have a 300X300px block called "Statistics" or "Friends" this block requires some database objects and logical operations that traditionally should be placed inside a controller, which prepares some instance variables that will be displayed nicely in it's view/partial.
This block could be called from many pages in my website, crossing various controllers and actions.
How can I go about this problem without repeating code inside controllers, nor placing logic inside views.
A bad solution would be to place SQL queries inside views, or using iframes where a single controller/action generates the expected HTML.
Any ideas will be greatly appreciated.
I think this is the kind of thing you should do in a helper method. It might be a good idea to use locals for you partial instead of instance variables so as not to pollute the namespace of your views:
module ApplicatonHelper
def friends_block
friends = Friend.where(...)
# Assuming the 'friends_block' partial is in a directory 'app/views/shared'
render :partial => "shared/friends_block", :locals => {:friends => friends}
end
end
The friends_block partial would use the local variable:
<div id="friends_block">
<% friends.each do |s| %>
...
<% end %>
</div>
And other views would just use the helper method without having to worry about anything else:
<%= friends_block %>
Have a look at the Cells gem:
https://github.com/apotonick/cells
I'd put the block into a partial and ensure that the required instance variables for that block are loaded in a before_filter on the relevant controllers and actions.
I'm just starting to tinker with extending the rails framework, and as an experiment, I thought I'd add some extra info inside the form_for helper. Specifically, when form_for is called, I'd like to generate an extra h1 tag such as:
# regular form_for <form> opening tag
<h1>Woohoo! It's added!</h1>
# tags fed into form_for via &proc
# form_for close <form> tag
At the moment I've added a /lib file that opens up ActiveRecord::FormHelper and overrides "form for". Needless to say writing out the whole form_for method with just the one added line added is dog ugly...but I can't call super() because, well, instead of inheriting from the method I'd like to super(), I've just overwritten it in /lib.
So, assuming I stubbornly want the functionality to be called via the same form_for tag (instead of, for example extended_form_for), what's the standard way for calling back to the original form_for method I'm overwriting? alias_method_chain? Thought I'd ask before I cement in some potentially lousy practices. If any hardened veterans could give an example I'd be appreciative.
Cheers
You could override form_for in your ApplicationHelper:
module ApplicationHelper
def form_for(*)
content_tag(:h1, "Woohoo! It's added!") + super
end
end
alias_method_chain is by far the simplest way to overwrite the method while still being able to call the original method. So in your lib file you'll want something like this:
def form_for_with_header(...)
form_for_without_header(...)
content_tag(:h1, "Header tag here")
# etc...
end
All my controllers inherit from applicatin_controller.rb, and I added:
helper :all
I want to use this function in my view to make url's like:
/post/some-title
instead of using the ID int he url
def post_path_for(post)
post_path(:id => post.title_parameterize)
end
This is rails 3.
Can't you use "to_param" in your model to change that without having to write a helper?
http://apidock.com/rails/ActiveRecord/Base/to_param
It depends on how you want to use it.
If it's in helper, you could call <%= post_path_for post %> in your view.
If it's in model, with small change you could call it like this: <%= post.path %>
Although second way is shorter, I usually put such functions in helpers, for the sake of separation of logic and presentation.
I agree with Nikita. It sounds like a helper to me. I use helpers for anything that is meant for display. It sounds like you want this available to all views. If that is the case, I would place it in helpers/application_helper.rb
+1 for Robin's to_param method. By using to_param, you could use the built-in url helpers (like link_to, url_for, ...natively)
For the other point, you mentioned you put it in controller and wanted to use it in view. You need the following line:
helper_method :post_path_for
I'm using the same layout for several controllers, and inside this layout I include a menu using a call to a helper, like this:
<%= side_menu %>
What I'd like to do is vary the contents of side_menu depending on the controller that's invoking the layout. In an ideal world, I could define side_menu in application_controller.rb and in other helper files and then the appropriate helper would be selected depending on the controller; in other words, something like this:
# application_helper.rb
def side_menu
"generic menu This goes here"
end
# users_helper.rb
def side_menu
"menu for users goes here"
end
# guests_helper.rb
def side_menu
"menu for guests goes here"
end
This doesn't work because in Rails 3 all helper files are loaded and I have no control over which side_menu will actually be called. It would be great if there were an option to load only application_helper.rb and the controller-specific helper, but there's not one (yet).
What's the best way to vary the content of a helper depending on the controller? I'm currently defining side_menu once in application_helper.rb and then checking to controller to see what to add. This feels wrong, since the problem nearly screams for a subclass-and-override answer -- which I can't do due to the "helper :all" behavior of Rails 3. Suggestions?
You can define this method in controller and add:
helper_method :side_menu
But maybe different solution would be better. I think that you can add _side_menu.html.erb in each controllers view folder and when you call <%= render :partial => 'side_menu' %> it should look for different files depending on current controller (however rememeber to add this file for all controllers).
Or you can mix these two methods. Add this helper method to controller and inside it render right file. This way it is better, because you get some default side menu and it won't crash when there is no side menu partial for a controller.
You can also in layout add <%= yield :side_menu %> and if you want to put something in side menu, just add <% content_for :side_menu do %> bla bla bla <% end %>.
In my rails application, I render a partial on multiple pages, and in that partial is a variable. So currently, lets say I have 5 pages that render :partial => "partialname", and inside of partialname is #variable.
Can I have it so that partialname has its own action with #variable instantiated inside, rather than having #variable be called 5 times from each action that renders the partial?
Thanks!
I would create a before_filter on all the methods that need the common behavior.
But if you really want the partial to have its own "action," make a helper method that does whatever "action-y" things you want and then renders the partial. That works out to essentially the same thing. I've done this before to make a template-type partial that contains various pieces of data that need processing.
Rails Sub-controllers?
See my answer on this.
Very similar method here, using before filters either using controller inheritance or modules when needed.
So, is this a problem of code running 5 times per request that you'd rather not? Like, you've got a partial and in it is:
#my_var = MyModel.some_expensive_method
If so, you could just cache the result in the model:
def cached_some_expensive_method
#some_expensive_method ||= some_expensive_method()
end
you could load #variable from the view:
<% #variable = Variable.find(:whatever) %>
but some consider this bad practice in not adhering to strict MVC. This does have the benefit of supporting fragment caching out of the box:
<% cache({:variable_id => :whatever}) do %>
<% #variable = Variable.find(:whatever) %>
. . .
<% end %>
Is there a common model that's being rendered in the main views that you could delegate the variable access to?
<%=h #model.variable %>