I'm following the instructions at: http://agilewebdevelopment.com/plugins/acts_as_taggable_on_steroids to add the tag cloud to my view:
in the controller:
class PostController < ApplicationController
def tag_cloud
#tags = Post.tag_counts
end
end
I also added the tag_cloud method as a helper method in the controller
and in the view:
<% tag_cloud #tags, %w(css1 css2 css3 css4) do |tag, css_class| %> (line 1)
<%= link_to tag.name, { :action => :tag, :id => tag.name }, :class => css_class %> (line2)
<% end %> (line 3)
However:
1) if I don't add the helper_method :tag_cloud in the controller I get a undefined method error for tag_cloud
2) if I do add the helper method I get: wrong number of arguments (2 for 0) on the same line 1 of my sample code above.
Suggestions?
SOLUTION
I ended up not doing what I had as example code in the view.
Instead I did this:
<% #post.tags.each do |tag| %>
<%= link_to( tag.name,tag,:class => "tag_cloud_item_link") %>
<% end %>
1.
Methods defined in the controller are not accessible to views unless you add (as you mention) the helper_method call.
2.
Your method tag_cloud that you've defined as a helper in your controller doesn't take any parameters, but you are trying to call tag_cloud with #tags, %w(css1...), & a block.
Your tag_cloud method will return an #tags instance variable and that's it.
From the post you've provided that you are working off of, did you include TagsHelper in your ApplicationHelper? I'm guessing that this defines a tag_cloud helper method that will accept the params that you are trying to pass in.
I'm having the same issue. Just like the OP, Moving the "tag_cloud" helper method to the TagHelper seemed to get rid of some issue, but creates the "wrong number of arguments" error in the process.
cbrulak said he found a work arround. Can you update us and possibly send a PM to the "Acts-as-taggable-on" authors at https://github.com/mbleigh/acts-as-taggable-on
I arrived here because I wanted to define a method to use in the view. The simple answer was that it should have been defined in the model (e.g. conversation.rb file), and not in the helper.
Related
Is it possible to generate a dynamic method using the strong parameter I get from my view?
In my view I will generate a different path according to the card the user clicks on. Then, in the controller I want to generate a dynamic method using the parameter obtained from the view, but I'm not sure how to write that. Thanks!
show.html.erb
<div class="branch-names">
<% #branches.each do |branch| %>
<div>
<%= image_tag "cat.jpeg" %>
<%= link_to "#{branch.name} Posts", send("#{branch.branch}_posts_path") %>
</div>
<% end %>
</div>
posts_controller.rb
def self.define_category(name)
define_method(name) do |params[:id]|
#posts = Post.where(category_id = params[:id])
end
end
define_category("#{params[:id]}")
You shouldn't define method based on user input. It may cause security issue, and for sure it causes performance penalty related to method cache invalidation.
Instead you can create one method that have an alternarive on params[:id] and then decide what to show to the user:
class MyController
def branches
case params[:id]
when('cat')
do_cat_stuff
when('dog')
do_dog_stuff
end
end
end
For having routes like /posts/cats you do not have to add dynamic methods. Think of branch like of an id of category:
routes:
resources :post_categories, only:[:index, :show]
view:
...
<%= link_to "#{branch.name} Posts", post_category_path(branch.branch) %>
PostCategories controller:
def show
#posts = Post.where(category_id: params[:id])
end
Also you can make posts a nested resource under categories and use a more RESTful structure with /post_categories/some_branch/posts mapping to posts#index
I have an ERB view with two blocks:
<%= test_h1 do %>
<%= 'test1' %>
<% end -%>
<%= test_h2 do %>
<%= 'test2' %>
<% end -%>
where test_h1 and test_h2 are similar helpers, but one is defined in a helper file, while another via helper_method in a controller:
module TestHelper
def test_h1(&block)
link_to '/url' do
capture(&block)
end
end
end
class TestController < ApplicationController
helper_method :test_h2
def test_h2(&block)
helpers.link_to '/url' do
helpers.capture(&block)
end
end
end
test_h1 produces the expected result and test_h2 renders the inner template block first:
test1
test2
Why? What would be an idiomatic way to write test_h2 ?
I think both examples of views should be re-written as:
<%= test_h1 do %>
<% 'test1' %>
<% end -%>
<%= test_h2 do %>
<% 'test2' %>
<% end -%>
My understanding that '<%=' forces to render the output of the block to the output stream, that was not an intended behavior in these two examples
capture overrides current output buffer and just calls the block (which is still bound to other view context), thus override has no effect when called from controller because view_context is not the same context the view is being rendered in.
To work around contexts you can define your helper like so:
# in controller
helper do
def test_h3(&block)
# this will run in view context, so call `controller.some_func` to access controller instance
link_to '/url' do
capture(&block)
end
end
end
When using capture from your controller the output is appended to the page buffer, as a result the <%= from of your erb is outputting immediately to the page output.
To work around, you need to use <% instead within your test_h2 block. So to get the expected behavior in both cases, use this syntax:
<%= test_h1 do %>
<%= 'test1' %>
<% end -%>
<%= test_h2 do %>
<% 'test2' %>
<% end -%>
More info in this article: https://thepugautomatic.com/2013/06/helpers/
The idomatic way to do it in rails would be to move the test_h2 method to a concern and include that concern in controller as well as helper class.
Or else define test_h2 as helper_method in your controller class.
But generally methods that are needed in multiple places should be placed in concerns, and include those concerns wherever needed.
Also if you need methods for views, then include concerns or define your own methods inside helpers.
Refer Can we call a Controller's method from a view (as we call from helper ideally)?
How to use concerns in Rails 4
I have an Each/do block in my view currently, but I'd prefer to push this code into a helper, as I need to add a few conditional statements in there so I don't want to clutter up my view. Here is the view I have currently that I have been trying to code as a helper method with no luck so far
<% update.voters_who_voted.each do |voter| %>
<%= link_to profile_path(voter) do %>
<%= thirty_avatar(voter) %>
<% end %>
<% end %>
How would this translate into a helper with this name
def find_voters_who_voted(update)
...
...
end
I've tried this with no luck
def find_voters_who_voted(update)
update.voters_who_voted.each do |voter|
link_to profile_path(voter) do
thirty_avatar(voter)
end
end
end
Remember that all you are doing is displaying the return value of this method. It looks like you are expecting it to act as if it's part of the view, but that's not the way helpers work. Something like this would return the equivalent of your original code block
def find_voters_who_voted(update)
update.voters_who_voted.collect do |voter|
link_to profile_path(voter) do
thirty_avatar(voter)
end
end.join
end
I made this helper function in my application_helper.rb file:
def link_to_related(path)
link_to "Show", path
end
So I can use it in my forms like this:
<%= link_to_related(person_path(f.object.person)) %>
Is there a way to further simplify this so I can just say:
<%= link_to_related(:person) %>
I've been trying to get my head around this, but to no avail.
Thanks for any help.
If you're only using this helper to link to show actions, you don't need to specify the path, passing in the object should be enough:
def link_to_related(object)
link_to "Show", object
end
<%= link_to_related f.object.person %>
Although that's about as long as typing link_to "Show", f.object.person :)
Or rather I don't know how to specify the route for it.
I have my controller setup us:
def tags
#clients = current_user.clients.find_tagged_with(params[:tag])
end
and my views
Tags:
<% for tag in #client.tags %>
<%= link_to tag.name, clients_path(:view =>'tag', :tag => tag.name) %>
<% end %>
Only problem is that the link (clients_path) goes back to index and not 'all.' I know it has to do with changing the clients_path to somehow tell it to use 'all'. But I don't know how.
Any help?
Thanks
You can check your routes using rake routes.
I'm not sure what you mean by 'all' but if this is a custom method added to routes, then you should be able to use all_clients_path instead of clients_path.