我正在构建一个具有静态页面和动态页面(与产品相关)的产品。这两类页面都有不同的发布生命周期。与设计师合作的营销团队,发布静态页面和产品页面由工程团队发布。
静态页面位于public/home
,它们是自包含的。除了提供链接之外,他们不需要访问Rails基础结构。
在此设置中,我尝试实现以下行为:
当未经身份验证的访问者启动http://www.xyz.com时,应该将用户带到静态目标网页。
当经过身份验证的访问者启动http://www.xyz.com时,应该将用户带到产品登录页面(LandingsController,索引操作)。
在我当前的实现中,我检查用户是否在Rails世界中进行了身份验证并呈现静态页面或产品页面。
我想知道以下内容:
1)你如何处理这种情况?
2)有没有办法避免进入静态主页的Rails堆栈。
3)是否存在root_path方法的自定义,以根据上下文返回不同的根
答案 0 :(得分:4)
1)你如何处理这种情况?
常见答案如下:
class LandingsController < ApplicationController
before_filter :login_required
def index
...
end
...
private
def login_required
if not_logged_in? # This methods depends on your authentication strategy
send_file "/your/static/path/#{params[:action]}", :type => "application/html charset=utf8;"
return false # Halt chain
end
end
并且,根据每个操作和模板之间的对应关系,您可以进一步将login_required
方法抽象到ApplicationController中,并验证文件是否存在。
2)有没有办法避免进入静态页面的Rails堆栈
是。你必须接受我的话,因为我自己没有这样做,但你可以使用Rack middleware来做到这一点。 Here is an example如何做类似的事情,除了不是重定向,你将静态地提供文件(只需将文件头和File.read的结果设置为内容)这取决于您的身份验证库但是,我正在努力工作。
3)root_path方法是否有自定义以返回不同的方法 root基于上下文
您无法定义条件路由(即在routes.rb
文件中定义多个路由),但您可以覆盖ApplicationController中的root_url
方法,假设您使用的是命名路径{{1你的路线定义。像
root
然而,这听起来真的是一个坏主意,因为1)你应该指向同一个网址,并让控制器处理请求(你的链接应该是盲目的你带到哪里),2)它可能打破其他依赖class ApplicationController
def root_url(*options)
if logged_in?
"/return/something/custom"
else
super(*options)
end
end
end
和root_url
方法的东西。
答案 1 :(得分:3)
不幸的是,Rails的路由只能根据请求中的某些内容将请求路由到不同的控制器,从而使每个请求的会话数据无法访问。您当前的实施肯定是最常见的策略。我猜是这样的:
def index
if logged_in?
# any logged in logic you need.
else
render :file => 'public/home', :layout => false
end
end
重构它以使其感觉不那么“icky”的唯一方法是将该渲染调用移动到before_filter
。由于过滤器将包含rendered?
,因此根本不会调用您的操作。当然,您也可以在之前的过滤器中为redirect_to
另一个位置选择经过身份验证(或未经过身份验证)的请求,这样可以完全解决问题。
但是,某人确实有可能会有一个会话而没有登录(例如,如果他们去了另一个你没有用这种方式处理的页面),或者甚至有无效的会话数据,所以你不会能够真正消除你现在拥有的代码。这些更改只会提高无会话请求的性能,但除非这些页面导致严重问题(我怀疑),所以我不建议这样做。