控制器最佳实践

时间:2014-04-24 18:07:53

标签: ruby-on-rails ruby ruby-on-rails-4

我有Cards Controller我需要设置类别。因为监督这个控制器的视图会非常沉重,所以我将所有内容都分成了文件夹。

的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

查看文件夹:

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

现在我认为这不是一个好主意,但就目前而言,我不知道有什么更好的方法。

我的凌乱控制器将如下所示:

  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

等...

现在......这个清单会很长......

  

有没有更好的方法来解决这个问题?

2 个答案:

答案 0 :(得分:3)

首先说一句:在您的示例中(我认为是您的应用程序的简化版本),您的控制器只是启动视图。如果这是正确的,页面也可以是完全静态的(纯HTML)并静态提供。

现在,我认为你应该有更多的资源:阶级,稀有,类型和种族可以是自己的资源,具有不同的"值"是页面。毕竟(我可以用我的RPG知识推断),这些是你的领域模型的元素,因此它们应该作为资源发挥作用​​。

这些文件夹已经是这样了,所以这可能会给出类似的结果:(警告,我的头上的伪代码)

resources :classes do # ClassesController
  collection do
    get 'druid'
    get 'mage'
  end
end

resources :rarity do # RarityController
  collection do
    get 'rare'
    get 'common'
end

最后,永远不要忘记控制器&路由文件只是ruby代码。你可以在那里制作循环:

cards_list = ['rogue', 'druid', ...]

resources :cards do
    collection do
      cards_list.each do |card_name|
        get card_name
      end
    end
  end
end

这也适用于上面的资源版本。

某些元编程可以在您的控制器上实现相同的功能(如果各种操作方法之间没有任何不同)。

答案 1 :(得分:0)

更新时间:2014年4月24日

根据您保持单独视图的绝对需要,我将定义如下路线:

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

在您的控制器中:

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

为了更准确,我需要查看卡模型的架构。


虽然马丁的解决方案肯定会正常工作,但我可能会朝着这个方向前进,并避免对不同类型,类等进行硬编码:

# This sets up routes for :new, :create, :show, :update, :delete, :edit, :index
resources :cards

如果你想获得一个'德鲁伊'您的规格/测试中的卡片:

get :index, {kind: 'druid'}

我的控制器方法看起来与此类似:

def index
    @cards = Card.where("kind = #{params[:kind]}")
    render "cards/class/#{params[:kind]}"
end

您甚至可以将视图设置为单个ERB或HAML模板,该模板可能足够通用以处理不同类型的属性。在这种情况下,你将摆脱或改变“渲染”#39;上面的行,让它默认为' index'或者' cards / class / index.html.erb'或者其他什么。

这只是我的头脑,但我倾向于避免对属性进行具体编码,而是将它们视为“卡片”的属性。毕竟,如果'卡'是资源,然后所有种族,稀有,阶级等只是一张牌的属性。

希望这一切都有道理。如果我能进一步澄清,请告诉我。 '''属性可能与“卡片”的数据库模式模型有所不同。