我正在努力使顶级路由以这种方式从我的Rails API工作到Ember.js客户端(例如,类似于GitHub的工作方式):
点击www.example.com/username
会给你一个用户的页面。这可能会点击api.example.com/users/:username
端点或其他某个端点。
点击www.example.com/organization_name
会给你一个组织的页面。这可能会点击api.example.com/organizations/:organization_name
端点或其他某个端点。
获取随机网址时,客户端显然不知道它正在处理哪种类型的模型。它只会将其视为www.example.com/random_string
,其中random_string
可以是username
或organization_name
。
我不太确定如何处理这种情况。目前还不清楚客户端或服务器的责任在哪里。我可以想象也许某种多态性在这里工作,但不能连接点。
修改
看起来这似乎可以在Rails端通过为/:slug
设置一个包罗万象的路由,然后使用slug首先查询User
,然后查询{{ 1}}。
更重要的问题是,通过使用现有的控制器操作进行渲染,还是让HTTP通过重定向处理它来处理这些请求是否有意义。 Organization
会很好地处理HTTP重定向吗?在另一种情况下,它是否能够在此端点上正确切换类型?
答案 0 :(得分:3)
看起来这似乎可以在Rails端通过为/:slug设置一个catch-all路由,然后使用slug首先查询User,然后查询一个Organization。
这是唯一可行的方法。您需要在 config / routes.rb 文件的最后添加此catch-all路由。我建议您将此路由与控制器中的代理方法相关联,该方法将确定User
或Organization
记录是否与slug
相对应。
当User
和Organization
具有相同的slug
时,您必须考虑应用操作(有些会优先考虑其中一个,有些会给访客提供2个选择);以及当没有记录对应slug
时要采取的行动(有些会显示404,有些会路由到列表页面)。这些选择将帮助您确定代理方法的更好设计。
这里主要的是设计这个代理方法。
1- HTTP重定向
您的代理方法会将redirect_to
回复给 / users /:slug 或 / organizations /:slug ,具体取决于& #39;来自slug
。
2- Ajax响应
与HTTP重定向类似,但在AJAX中完成。您的代理方法会显示一个包含JavaScript代码的页面,该代码可以获取 / users /:slug 或 / organizations /:slug 的内容并显示它通过AJAX。
此外,可以使用history.pushState
3-服务器端代理
您的代理方法将执行与您的端点方法相同的代码。这意味着如果发现slug
与User
记录相对应,代理方法将与UserController#show
相同。 (同样适用于Organization
)
这意味着代理方法必须调用UserController#show
所有的前/后过滤器,并呈现相同的视图。
如果你选择这个DRY解决方案,请非常谨慎。或者您可能最终难以维护您的应用程序。
没有一种方法可以做到这一点,这完全取决于您的应用程序架构。例如,如果您的show
方法只是获取记录并呈现视图,并且没有控制器帮助方法,那么它的简单和安全。另一方面,如果你有过滤器和控制器助手方法比它变得有点棘手。在这种情况下,您可能需要依赖控制器问题。
答案 1 :(得分:3)
为路径创建新模型,它将属于用户或组织。给它一个唯一的字符串,让它决定它属于谁:
在模型上:
has_one :route_name
before_create :create_route
def create_route
self.create_route_name(path: self.path) #change this to what ever the user wants
end
关于组织和用户:
RouteName.find_by(name: "blah_blah").owner
然后你可以这样做:
eval()
答案 2 :(得分:2)
假设我们有一个用户和一个组织,我们可以执行以下操作:
class User < ActiveRecord::Base; end
class Organization < User; end
(您需要用户表上的类型字段,用户和组织将共享)
他们将共享数据库字段,而Organization类将继承用户拥有的所有内容(包括默认范围和验证)。如果您的模型相似,这是非常有用的,因为您可以保持一切干燥(您不必定义任何额外的东西)。
Organization.create(name: "thisisanorganization") #=> true (assume that name is unique)
User.create(name: "penne12") #=> true (assume that name is unique)
User.find_by(name: "thisisanorganization") #=> Organization
User.find_by(name: "penne12") #=> User
Organization.find_by(name: "thisisanorganization") #=> Organization
Organization.find_by(name: "penne12")
您可能还会发现为用户和组织创建父类很有用,因此用户可以使用独特的方法和方法。来自组织的验证(组织不需要密码,组织属于许多所有者(类:用户),组织必须有项目,用户有电子邮件等)