Reputation: 7941
I have a Cards Controller
where i need to set up categories. Because the views for this Controller would get pretty heavy to oversee i divided everything in folders.
routes.rb
resources :cards do
collection do
get 'druid'
get 'hunter'
get 'mage'
get 'paladin'
get 'priest'
get 'rogue'
get 'shaman'
get 'warlock'
get 'warrior'
get 'free'
get 'common'
get 'rare'
get 'epic'
get 'legendary'
get 'spell'
get 'minion'
get 'weapon'
get 'beast'
get 'deamon'
get 'dragon'
get 'murloc'
get 'pirate'
get 'totem'
end
end
View Folders:
Views ->
cards ->
class ->
druid.html.erb
hunter.html.erb
mage.html.erb
paladin.html.erb
priest.html.erb
rogue.html.erb
shaman.html.erb
warlock.html.erb
warrior.html.erb
rarity ->
free.html.erb
common.html.erb
rare.html.erb
epic.html.erb
legendary.html.erb
type ->
spell.html.erb
minion.html.erb
weapon.html.erb
race ->
beast.html.erb
deamon.html.erb
dragon.html.erb
murloc.html.erb
priate.html.erb
totem.html.erb
Now i don't think this is such a good Idea, but as for now i don't know any better way of doing it..
My messy controller will look like this:
def druid
render 'cards/class/druid'
end
def hunter
render 'cards/class/hunter'
end
def mage
render 'cards/class/mage'
end
def paladin
render 'cards/class/paladin'
end
etc...
Now... This list will get pretty long...
Is there a better way of dealing with this ???
Upvotes: 3
Views: 763
Reputation: 1100
UPDATE: 04/24/2014
Based on your absolute need to maintain separate views I would define the routes like this:
resources :cards do
collection do
get :cards, path: '/cards/:arg1'
end
end
OR
resources :cards do
collection do
get :cards_by_class, path: '/cards/class/:class'
get :cards_by_race, path: '/cards/race/:race'
#etc...
end
end
In your controller:
def index
template, @cards = get_cards
# you need to determine the path to the views based on params[:arg1]
render template
end
private
# These constants could be defined in the Card model itself
CLASS_TYPES = %w(druid hunter mage paladin) # etc.
RARITIES = %w(free common rare epic legendary)
WEAPON_TYPES = %w(spell minion weapon)
RACE_TYPES = %w(beast demon dragon) # etc.
def get_cards
path = ""
cards = nil
case params[:arg1]
when CLASS_TYPES
# Substitute 'classtype' with the proper column name
cards = Card.where("classtype = '#{params[:arg1]}'")
path = "/cards/class/#{params[:arg1]}"
when RARITIES
# Substitute 'rarity' with the proper column name
cards = Card.where("rarity = '#{params[:arg1]}'")
path = "/cards/rarity/#{params[:arg1]}"
when WEAPON_TYPES
# Substitute 'weapon_type' with the proper column name
cards = Card.where("weapon_type = '#{params[:arg1]}'")
path = "/cards/type/#{params[:arg1]}"
when RACE_TYPES
... # you get the idea
end
return path, cards
end
To be more accurate, I would need to see your schema for the Card model.
Although Martin's solution would surely work just fine, I would probably go in this direction, and avoid hard-coding the different types, classes, etc:
# This sets up routes for :new, :create, :show, :update, :delete, :edit, :index
resources :cards
If you want to get a list of 'druid' cards in your spec/test:
get :index, {kind: 'druid'}
My controller method would look similar to this:
def index
@cards = Card.where("kind = #{params[:kind]}")
render "cards/class/#{params[:kind]}"
end
You could even make the view a single ERB or HAML template that may be generic enough to handle the different types of attributes. In that case you would get rid of, or change, the 'render' line above and let it default to 'index' or 'cards/class/index.html.erb' or whatever.
This is just off the top of my head, but I would tend to avoid concrete-coding the attributes, and instead treat them like properties of a 'card'. After all, if the 'card' is the resource, then all of the races, rarity, class, etc. are just attributes of a card.
Hopefully this all makes sense. Let me know if I can clarify further. The 'kind' attribute maybe something different in your DB schema model of the 'Card'.
Upvotes: 0
Reputation: 7723
A remark first: in your example (which I suppose is a simplified version of your application), your controller is just firing up the view. If this is correct, the pages could as well be totally static (pure HTML) and served statically.
Now, I think you should have more resources there: class, rarity, type and race could be resources by themselves, with the different "values" being the pages. After all (for what I can infer with my RPG knowledge), those are the elements of your domain model, so they should work great as resources.
The folders are already like that, so this could give something like: (warning, pseudo code out of my head)
resources :classes do # ClassesController
collection do
get 'druid'
get 'mage'
end
end
resources :rarity do # RarityController
collection do
get 'rare'
get 'common'
end
Finally, never forget that controllers & the routing file are just ruby code. You can make loops there:
cards_list = ['rogue', 'druid', ...]
resources :cards do
collection do
cards_list.each do |card_name|
get card_name
end
end
end
end
This would work for the version by resource above too.
Some metaprogramming could achieve the same on your controller (if you have nothing different between the various action methods).
Upvotes: 3