1

可以说,为了这个问题,我有两种用户类型:type1& type2。我希望 Rails 根据显示的用户类型使用控制器/模块。例如:

如果User(id: 1, type: 'type1')hastype1User(id: 2, type: 'type2')has type2,则转到:

/users/1

将选择 Type1::UsersController。并去:

/users/2

将选择 Type2::UsersController。

这将允许我为每种类型使用不同的控制器和视图。

注意:我不希望type在 URL 中显示,我希望它是动态的。

4

2 回答 2

2

正如 GoGoCarl 所说,这并不是真正的 Rails 做事方式。也就是说,让它发挥作用并不难。你可以做这样的事情routes.rb

get 'users/:id', to: 'type1/users#show', constraints: lambda { |request| 
  _id = request.fullpath.gsub('/users/','').to_i
  # Note: there might be an easier way to get ID from the request object
  User.find(_id)._type == 'type1'
}
get 'users/:id', to: 'type2/users#show', constraints: lambda { |request| 
  _id = request.fullpath.gsub('/users/','').to_i
  User.find(_id)._type == 'type2'
}

在我的示例中,我已将您的type字段重命名为_type(因为 Railstype用于单表继承)。我已经对此进行了测试,并且可以按需要工作。

于 2013-07-05T18:19:54.307 回答
0

这是可能的,但你会做很多(可能)不必要的与 Rails 方式的斗争。我认为你会想要一个控制器,因为可能有相当多的共享逻辑(例如保存、删除、创建等)。

要回答您的问题(因为我讨厌人们留下建议而不是答案),那么您需要创建一个扩展路由的模块,这将允许您进行自定义匹配。从那里,您可以进行适当的检查和路由。 这是一个例子

也就是说,更好的方法(不是双关语)是拥有一个控制器,它具有可以选择视图的集中方法。

def find_view view_name
  "#{view_name}#{@user.type}"
end

因此,对渲染 find_view('new') 的调用将尝试渲染名为“new-type1”的视图。您可以将所有 type1 用户特定逻辑放在该视图中。用户类型 2 相同。

同样,由于我认为您的用户代码中会有很多重叠,您可能希望将此 find_view 方法推送到帮助程序类,以便您可以从视图中调用它,并根据用户类型执行诸如渲染特定部分的事情. 这将允许更多的代码重用,这绝不是一件坏事。

一旦你开始考虑拥有一个控制器,有许多简单的方法可以将特定于用户类型的代码推送到不同的途径——上面解释的视图方法,你可以将所有相关代码推送到单独的助手它们是根据用户类型动态调用的,我相信还有更多(可能更好)。但是所有这些都有一个主要的共同点——如果你屈服于让 Rails 使用一条路线、一个控制器,你将减少与 Rails 的斗争,并且你将减少重复的代码。

祝你好运,希望有帮助。

于 2013-07-05T18:01:12.077 回答