2012-02-06 73 views
1

我遇到了10个资源(控制器)对应于10个数据库条目的情况。特别是关于建筑物。有一个镇中心控制器,锯木厂控制器等等。如何处理这些资源

我不想创建一个buildings_controller并处理所有内容,因为每个建筑的行为都非常不同。

但我对路线有疑问,以及如何处理特定情况。我最好想有像这样的网址:

/town_center/view 
/sawmill/view 

这很好,但我有一个根本性的问题。没有简单的方法从url中获取town_center ID号码。我当然需要这些信息,以获得关于特定建筑物的模型信息。现在,人们可以说,我就可以用这个:

/town_center/view/1 
/sawmill/view/2 

这似乎很好,但带来了另一个根本的问题,那就是,我必须指定ID,当我从另一个控制器重定向。假设我想重定向到town_center控制器。我需要做的:

redirect_to town_center_url(1) 

,我真的不喜欢,因为ID可以在我的数据库随时更改,一般是肯定的,很容易出错,一个不好的编程习惯。

你将如何处理?我错过了一个更简单的方法?

编辑:

所需要ID

scope :path => '/town_center', :controller => :town_center do 
    get '/view/:id' => :view, :as => 'town_center' 
    end 

    scope :path => '/sawmill', :controller => :sawmill do 
    get '/view/:id' => :view, :as => 'sawmill' 
    end 

用法示例的

示例将来自/概述开始,我们看到这样的建筑链接的列表:

/town_center/view/1 
/sawmill/view/2 

如果点击第一个,则执行具有:id为1的视图动作。很好,直到现在。但是在这个视图模板上说,有一个像send_message这样的动作。现在,这个动作是这样的:

def send_message 
    send_the_message_blah_blah 
    redirect_to sawmill_url(2) 
end 

现在,我想这个问题是清楚的。为了重定向到锯木厂viewpath,我需要知道它的ID,这意味着我将不得不付出额外的查询,没有真正的理由,如:

def send_message 
    send_the_message_blah_blah 
    redirect_to sawmill_url(Building.where(:name=>'sawmill').first) 
end 

如果我不包括:在所有网址的id,然后我的视图操作只是不知道它应该参考的建筑物。

+0

我很困惑,你可以发布你的'routes.rb'吗? – Azolo 2012-02-06 06:11:26

+0

编辑说明我目前的路线 – Spyros 2012-02-06 06:13:49

+0

你知道你可以在你的路径/网址中使用实例变量吗?除非我误会,否则这不会让你容易吗? redirect_to town_center_url @some_town_center – KobeJohn 2012-02-06 06:20:08

回答

1

因此,如果是我,我会改变我的routes,并把before_filter在每个控制器,为您查询。

所以像你的每一个routes都会看起来像这样。

scope :path => '/sawmill', :controller => :sawmill do 
    get '/view' => :view, :as => 'sawmill' 
end 

然后在SawmillController您将添加过滤器之前的获得从数据库中sawmill

class SawmillController < ApplicationController 
    before_filter :get_sawmill 
    ... 
private 
    def get_sawmill 
    @sawmill = Building.where(:name=>'sawmill').first 
    end 
end 

这样,任何时候有人对控制器采取行动,他们甚至不会知道它背后有一个数据库。控制器在之后执行所有的配合请求。

这种方式完全可以将:id从您的网址和_url方法中删除。意思只是sawmill_url而不是sawmill_url(1),你的网址是/sawmill/view。干净又干净!

+0

这是我想避免真正的。我想到了这样的事情,这就是我最初提出这个问题的原因。看来,也许我只需要坚持每次我想重定向这种方式专门执行查询。 – Spyros 2012-02-07 00:07:12

+0

咦?这样查询才会在查看页面之后才执行。如果你正在查看'数据库'信息,那么这将只是在同一时间加载数据。 url方法应该是'sawmill_url',而实际的url将会是'/ sawmill/view'而不用':id' – Azolo 2012-02-07 00:12:59

+0

噢,对不起,我误解了,我的不好。所以你只是得到一个实例变量,是第一个数据库条目。这非常有趣,确实是一个很好的解决方案。给我一些时间来测试它,看看它在我的应用程序中是如何工作的。无论如何,+1,好主意。 – Spyros 2012-02-07 00:22:46

0
match '/town_center/view/:id' => 'town_center#view' 

如果你在控制器中有一个视图动作,但你为什么要反对这个约定。只是有:

resources :town_center 

你会打电话town_center(instance_of_a_town_center),这将使你的路径

/town_center/1

为什么你需要的观点?它只是town_center控制器中town_center实例的get方法。

希望这有助于

+0

这实际上在上述评论中提到我的问题。使用实例会非常繁琐,因为我需要获取它,从而执行无用的查询。我并不特别需要这个观点,但我认为,因为只有一个城镇中心,所以town_center/view会更有意义。 – Spyros 2012-02-06 10:33:53

0

这让我觉得要么你不明白轨方式要你做的事情,或者你的情况有一些特殊的考虑,我们仍然不知道的:

(编辑:看着你的答案的历史,好像你知道更多关于轨道比我这样做,我猜这是第二个请跳过这个问题的底部,我对你的要求。)

redirect_to town_cente r_url(1) 我真的不喜欢,因为ID可以随时在我的 数据库中更改,通常是一个糟糕的编程习惯,肯定会出错,非常容易出错 。

我知道的唯一的解决方案是通过一些其他的上下文信息来访问没有某种id的资源。例如,使用设计认证系统,您不会在任何地方使用您的ID。如果你是通过身份验证的,那么服务器知道你是谁,不想在URL或其他任何东西中不必要地抛出你的ID。同样,如果您有人登录,您可以通过他们的会话识别他们的资源。

例如控制器(也许应该是在一个小镇的模式实际上):

@tc = current_user.town_center 
@b = current_user.barracks 

视图

<%= link_to 'Town Center', @tc %> <%# which still is using some identifier %> 

或者,如果你有一个 “位置”,那么你可以找出孤独的通过类似于上述位置的town_center(但现在您需要位置标识符)。

基本上,除非你有一些特殊的上下文,否则你需要一个标识符。

如果这没有帮助,我认为你应该引导我们通过一个例子说明如何让事情从零开始(用户进入你的页面,他们看到了什么?)......以某种方式打开建筑资源(建筑物何时可用?)以......对该建筑物采取一些行动。

+0

嗨那里,thanx答复。是的,我其实知道使用一个实例变量来做到这一点,但它似乎是我想要的很少。如果你从零开始考虑它,认为有许多建筑物,但每个实际上是不同的资源。现在,例如,town_center指的是Building模型中的一个town_center条目。现在,我通常不会使用ID,因为它不是必需的。但是,当我尝试在我的视图操作中访问/ town_center/view时,我无法找到获取town_center建筑信息的好方法(我不想要会话变量)。 – Spyros 2012-02-06 18:00:15

+0

为更多我现在编辑我的文章。 – Spyros 2012-02-06 18:00:56