Reputation: 5400
very new to rails. I've been following a book which helps a lot, but this I can't figure out:
I have a controller Techniques with some actions (methods) in it:
def patadas
@technique = Category.find(4).technique
end
def golpes
@technique = Category.find(3).technique
respond_to do |format|
format.html { redirect_to(patadas_path) }
end
end
The idea is to have a single page where I can send different techniques to and it will render them. The patadas.html.erb page has this in it:
[ some html ]
<% if @technique then %>
<% @technique.each do |p| %>
(<%= p.order %>) <%= p.korean %> - <%= p.spanish %><br />
<% end %>
<% else %>
No techniques specified to show!
<% end %>
My problem is with the redirect. I want to be able to send different methods to that same page (obviously I'd have to rename it to techniques or something other than patadas) and have it render the technique that corresponds to the method called. Right now the redirect gets executed, but it shows the patadas method always.
Oh, I have this in the routes.rb file:
match '/patadas' => 'techniques#patadas', :as => 'patadas'
match '/golpes' => 'techniques#golpes', :as => 'golpes'
All the tutorials and books, etc I've seen explain how to do it for one view for each action, but this is really wasteful, I want one view for all these different actions. With the above routes I understand that if I build another view called 'golpes.html.erb' it would render them, but I'm looking for a single view with different actions.
Thanks.
PS Also, is it possible to have something like this:
@frontal.each { |p| puts "(#{p.order}) #{p.korean} = #{p.spanish}" }
in a view (html.erb) file? It's much more elegant than the above craziness of opening and closing <%= %> tags. With the beauty of Ruby, it seems wasteful to use such a syntax. I'm sure there must be but I haven't gotten that advanced yet :)
Edit: In view of all the changes I've made (created a scaffolding for the Category), I'm rewriting the question to make things clearer. So now this is what I have:
categories_controller.rb
[ bunch of stuff ]
def show
@category = Category.find(params[:id])
end
routes.rb
resources :categories
In the show file I'd like to list all categories by id so the /categories/show.html.erb file:
I want to get category.order, category.category, category.spanish to show here
<%= link_to 'Edit', edit_category_path(@category) %> |
<%= link_to 'Back', categories_path %>
Please excuse my idiocy, but I can't figure out what to put in this file to list the content. If I try to do something like:
<% @category.each do |cat| %>
<li><%= cat.category %> - <%= cat.spanish %></li>
<% end %>
I get an error
undefined method `each' for #<Category:0x007f81c42a3fd0>
(The original question had to do with routes, I wrongly wanted routes to handle different actions, something that is actually done with the show template, hence jimworm's answer. I edited the question for clarity since I changed so many things, but can't really remember the original phrasing, sorry)
Upvotes: 1
Views: 1051
Reputation: 2741
Welcome to the Rails way, please ask more if you're still stuck.
Redirects are redirects, no information is preserved between requests. Looks like you're trying to list techniques for each category? Keep in mind that the only input you have is a category, not anything to do with techniques. I'd recommend a nested route in this case.
# config/routes.rb
# this gives you the route /categories/:category_id/techniques, among other things
resources :categories do
member do
resources :techniques
end
end
# app/controllers/techniques_controller.rb
# note that this is only called from inside the nested route
# so params[:category_id] is available
class TechniquesController < ActionController::Base
def index
@category = Category.find params[:category_id]
@techniques = @category.techniques
end
end
# app/views/techniques/show.html.erb
<% @techniques.each do |technique| %>
<p>(<%= technique.order -%>) <%= technique.korean -%> - <%= technique.spanish -%></p>
<% end %>
Note the usage of params[:category_id]
instead of fixed route names. You could always use friendly_id
to find categories by a slug instead of an integer.
https://github.com/norman/friendly_id
Edit: Addressing your comment one point at a time (but not in the right order):
In Rails convention, there's a big difference between technique
and techniques
. A seasoned Rubyist would never name a list of techniques technique
, because that's just confusing! An instance of Technique
must be a technique, so to speak, and if there's more than one technique in each instance of that model, you'd call it TechniqueList
or TechniqueGroup
or something.
What you're asking for is to have a list of techniques displayed on a category's show
action. In that case, you won't need the nested route. You could use the same method to show a list of categories for a particular technique (provided that you have a many-to-many relationship between categories and techniques).
# app/controllers/categories_controller.rb
class CategoriesController < ActionController::Base
def show
# `includes` joins the techniques table, avoids n+1 lookups
@category = Category.includes(:techniques).find params[:id]
end
end
# app/views/categories/show.html.erb
<% @category.techniques.each do |technique| %>
<p>(<%= technique.order -%>) <%= technique.korean -%> - <%= technique.spanish -%></p>
<% end %>
Sub-categories: what are they? A model? A query on the Category
model? I'm going to treat it like a query in the code below.
# app/models/category.rb
class Category < ActiveRecord::Base
class << self # this adds class methods
def sub_category_query(param)
# this line is an example only, it depends on your query
where(:sub_category => param)
end
end
end
# app/controllers/categories_controller.rb
class CategoriesController < ActionController::Base
def sub_category
@categories = Category.sub_category_query params[:sub_category]
# since it's just showing a list of categories
# you can probably reuse the index template here
render :index
end
end
# config/routes.rb
resources :categories do
collection do
# this give you an extra route to search by sub-category
# rails guesses the action name, and expects a param here
get 'sub_category/:sub_category'
end
end
Upvotes: 1