我遇到的情况是我有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,那么我的视图操作就是不知道它应该引用什么构建。
答案 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(但现在您需要位置标识符)。
基本上,除非你有一些特殊的上下文,否则你需要一个标识符。
如果这没有帮助,我想你应该向我们介绍一下你希望如何从零开始工作的一个例子(用户来到你的页面。他们看到了什么?)到......某种程度上打开建筑资源(建筑物什么时候最初可用?)到...对该建筑物做一些动作。