Newbie - Create menu and send parameters to controller from view.

Hello!

I'm trying to create a menu. I have a controller that takes two
attributes, like this:

def category(gender, category)
  @ads = Ad.find_all_by_gender_and_category(gender,
category).paginate(:page => params[:page])
  @title = "Startsidan"
  render 'home'
end

And in my view I have a list with menu options:

<li class="li_content"><%= link_to "Accessoarer", :action =>
"category('dam', 'Accessoarer')" %></li><br />

And my routes it look like this:

match '/dam-accessoarer', :to => "pages#category('dam',
'Accessoarer')"

But it doesn't work.

I get the following error.

Unknown action

The action 'category('dam', 'Accessoarer')' could not be found for
PagesController

Any help on how to solve it would be greatly appreciated!

Thanks!
// Anders

Hello!

I’m trying to create a menu. I have a controller that takes two

attributes, like this:

def category(gender, category)

@ads = Ad.find_all_by_gender_and_category(gender,

category).paginate(:page => params[:page])

@title = “Startsidan”

render ‘home’

end

Is this your controller code? If so you have issues as (someone correct me if this is a new Rails 3 construct that I am clueless) you should not be taking arguments in the signature. If the params gender and category are needed they should be accessed as params[:gender] params[:category].

So in your view you need something like this below. Also see http://apidock.com/rails/ActionView/Helpers/UrlHelper/link_to for info on link_to helper.

<%= link_to “Accessories”, :controller => “categories”, :action => “show”, :gender => “male”, :category => “zzz”

and then in your controller action

def show
gender = params[:gender]
category = params[:category]

now do what you want with the data

end

David

Hi! Thanks for your help. But I still doesn't get it to work. I've
changed the controller action so it looks like:

def category
    gender = params[:gender]
    category = params[:category]
    @ads = Ad.find_all_by_gender_and_category(gender,
category).paginate(:page => params[:page])
    @title = "Startsidan"
    render 'home'
end

And in the view:

<li class="li_content"><%= link_to "Accessoarer", :action =>
'category', :gender => 'female', :category => 'Accessoarer' %></

<br />

When I press the link the url changes to this:

http://localhost:3000/kategori?gender=female&category=Accessoarer

I don't get any errors, but it doesn't find anything. Any idea on what
might be wrong?

// Anders

Hi! Thanks for your help. But I still doesn’t get it to work. I’ve

changed the controller action so it looks like:

def category
gender = params[:gender]

category = params[:category]

@ads = Ad.find_all_by_gender_and_category(gender,

category).paginate(:page => params[:page])

@title = "Startsidan"

render 'home'

end

And in the view:

  • <%= link_to "Accessoarer", :action =>
  • ‘category’, :gender => ‘female’, :category => ‘Accessoarer’ %></


    When I press the link the url changes to this:

    http://localhost:3000/kategori?gender=female&category=Accessoarer

    I don’t get any errors, but it doesn’t find anything. Any idea on what

    might be wrong?

    So you are rendering the ‘home’ view - can you show me this? Also, describe what you are expecting to see. Have you also verified that you are getting good values on @ads and @title (which I assume you are doing something with in your view)? I would recommend if you have not used it yet to get familiar with ruby-debug. This way you can step in to your controller in action and check these attributes (of course even better is get used to writing tests for your code, but I know this might be overwhelming at first).

    Let me know - if you need help with ruby-debug let me know — if so do give me the version of Rails and version of Ruby you are running.

    Hi!

    Here is what I think it the most relevant part of the home view,

    # Renders the menu
    <%= render "shared/categories" %>
    .
    .
    .
    # Renders ads, unless its empty
    <div class="right_container body_copy">
      <% if @ads.empty? %>
        Hittade inga annonser.
      <% else %>
        <%= render @ads %>
      <% end %>
    </div>

    <div class="paginate body_copy">
      <%= will_paginate @ads, :previous_label => t(:previous), :next_label
    => t(:next) %>
    </div>

    I'm getting "Hittade inga annonser" which means "Couldn't find any
    ads" when I click on the link, but it shouldn't be empty. It should
    render all ads that matches a certain condition, for example, :gender
    => 'female', category => ' accessories'. I have checked the database
    and it should get two rows.

    It works when I have methods like this:

    def female_accessories
      @ads = Ad.find_all_by_gender_and_category('dam',
    'Accessoarer').paginate(:page => params[:page])
      @title = "Startsidan"
      render 'home'
    end

    But this isn't very DRY, since I would need to have an action for
    every category. I want something slightly more dynamic.

    I hope i'm understandable.

    Tips and links regarding ruby-debug would be really nice!

    Thanks!
    // Anders

    Hi!

    Here is what I think it the most relevant part of the home view,

    Renders the menu

    <%= render “shared/categories” %>

    .

    .

    .

    Renders ads, unless its empty

    <% if @ads.empty? %>

    Hittade inga annonser.
    

    <% else %>

    <%= render @ads %>
    

    <% end %>

        <%= will_paginate @ads, :previous_label => t(:previous), :next_label
    

    => t(:next) %>

    I’m getting “Hittade inga annonser” which means "Couldn’t find any

    ads" when I click on the link, but it shouldn’t be empty. It should

    render all ads that matches a certain condition, for example, :gender

    => ‘female’, category => ’ accessories’. I have checked the database

    and it should get two rows.

    It works when I have methods like this:

    def female_accessories

    @ads = Ad.find_all_by_gender_and_category(‘dam’,

    ‘Accessoarer’).paginate(:page => params[:page])
    @title = “Startsidan”

    render ‘home’

    end

    But this isn’t very DRY, since I would need to have an action for

    every category. I want something slightly more dynamic.

    Right - this is going to be a very ugly controller in no time. But fix the problem at hand and then you can play with making it dry. Google the
    term ‘named scopes’ in google and this may help. If nothing else, move this kind of logic into a model, it should not be in a controller. Controller ideally just handles requests and routing of them, business logic should be in models or other classes.

    I hope i’m understandable.

    Tips and links regarding ruby-debug would be really nice!

    This is probably a good place to pick up ruby debug.

    Do this:

    1. gem install ruby-debug
      (note if you are using Rails 3 and Ruby 1.9.2 you might need: gem install ruby-debug19. This is what I am using.)

    2. Now you can put a breakpoint wherever you want by typing ‘debugger’ where you want the execution to stop — so for example:

    def female_accessories
    debugger

    @ads = Ad.find_all_by_gender_and_category(‘dam’,

    ‘Accessoarer’).paginate(:page => params[:page])

    @title = “Startsidan”

    render ‘home’

    end

    1. Then restart your rails server:

    If Rails 3:
    rails server --debugger

    If < Rails 3:
    script/server --debugger

    1. Now execute your page - load the page. The execution will stop when you get to the break point. Go to your server console and you should see some familiar code and line number. From there you can type in whatever ruby you want to debug (like irb). Type ‘n’ to go to the next line, ‘c’ to continue.

    Using this you should be able to figure out what is going on in your code. Great tool to have, I use it often several times a day.

    Thanks for your tips, I think I will follow your suggestion and create
    a new model 'Category', think it will get a lot cleaner.

    Thanks.
    // Anders

    Glad to help. Definitely if you have not, at least for your models try to start writing some tests – I use rspec now but honestly if you are new to tdd you could use test/unit just fine and get used to the process. The way I see it is in the past before I wrote tests, I would write code and then spend time debugging. I found that writing tests as I go actually formalizes the debugging process I would go through, and then of course the result is a test suite you can run whenever you want — and at least you will know the things you are testing for still work! I promise you will get addicted.