如何处理这些资源

时间:2012-02-06 06:06:33

标签: ruby-on-rails ruby-on-rails-3

我遇到的情况是我有10个资源(控制器),对应10个数据库条目。特别是它涉及建筑物。有一个town_center控制器,一个锯木厂控制器等等。

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

但我对路线以及如何处理特定情况有疑问。理想情况下,我希望网址像:

/town_center/view
/sawmill/view

这很好,但我有一个根本问题。没有简单的方法可以从网址获取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

使用示例

从/ overview开始,我们看到一个建筑链接列表,如:

/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

现在,我想问题很明显。为了重定向到锯木厂的观察路径,我需要知道它的id,这意味着我必须进行额外的查询,没有真正的原因,如:

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

如果我根本没有在URL中包含:id,那么我的视图操作就是不知道它应该引用什么构建。

3 个答案:

答案 0 :(得分:1)

因此,如果是我,我会更改routes并在每个为您执行查询的控制器中添加before_filter

因此,您的routes中的每一个都会看起来像这样。

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

然后在你的SawmillController中添加before过滤器以从数据库中获取sawmill

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

这样,只要有人在控制器上采取行动,他们甚至不知道背后有数据库。控制器完成了所有的工作 AFTER

这样您就可以完全切断网址和:id方法中的_url。含义仅为sawmill_url而非sawmill_url(1),您的网址为/sawmill/view。干净整洁!

答案 1 :(得分: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方法。

希望这会有所帮助

答案 2 :(得分:0)

这让我觉得你不理解rails希望你做事的方式,或者你的情况有一些我们仍然不知道的特殊考虑因素:

(编辑:看看你的回答历史,你似乎对我的了解比我更多了所以我猜它是第二个。请跳到这个问题的底部以便我的请求)< / em>的

  

redirect_to town_center_url(1)   我真的不喜欢,因为id可以随时随地改变   数据库并且通常是一个糟糕的编程实践,当然,非常   容易出错。

我知道在没有某种id的情况下访问资源的唯一解决方案是通过其他一些上下文信息。例如,使用设计认证系统,您不会在任何地方使用您的ID。如果您经过身份验证,那么服务器就会知道您是谁,并且不希望在网址或其他任何地方不必要地丢弃您的身份。因此,如果您有人登录,您可以通过他们的会话识别他们的资源。

示例控制器(实际应该在城镇模型中):

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

查看

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

或者,如果您有“位置”,那么您可以通过类似于上面的位置识别单独的town_center(但现在您需要位置标识符)。

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

如果这没有帮助,我想你应该向我们介绍一下你希望如何从零开始工作的一个例子(用户来到你的页面。他们看到了什么?)到......某种程度上打开建筑资源(建筑物什么时候最初可用?)到...对该建筑物做一些动作。