`
netfork
  • 浏览: 481381 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

ror二级域名的猜想和实现

    博客分类:
  • Ruby
阅读更多

搜了一下关于ror二级域名的文章,都是零零散散的,最终也没能找到讨论明白的,下面是自己根据一些讨论提供的线索,猜想了一下实现的方式,可以实现类似javaeye的二级域名效果,但是可能实现的很粗笨很无知,所以请知情者狂拍我,不胜感激。

 

总体划分为两部分进行处理:

1、在routes.rb中,增加对没有controller请求的路由,并在ApplicationController中进行处理。主要解决直接以类似http://netfork.iteye.com访问的情况。

2、在ApplicationController中增加二级域名过滤器。主要解决以类似http://netfork.iteye.com/blog/XXX形式访问的情况。

 

先说第一部分的处理:

1、在routes.rb中增加下面的代码:

map.connect '', :controller => 'application', :action => 'subdomain_dispatch'
 

2、在ApplicationController中增加对应的action。具体参考以下代码示例,取得二级域名,如果非空也非www,则根据此域名取得对应的公司信息。

  # 二级域名路由
  def subdomain_dispatch
    # 取得二级域名
    subdomain_name = request.subdomains.first.to_s
    if !subdomain_name.blank? && subdomain_name != 'www'
      # 根据二级域名,取得对应的公司信息
      @company = Company.find_by_domain_name(subdomain_name)
      if @company
        # 声明布局模板
        render :template => "/company/show", :layout => "company"
      else
        redirect_to :controller => 'index'
      end
    else
      redirect_to :controller => 'index'
    end
  end
 

经过以上两步,直接以http://netfork.iteye.com这种形式请求时,就能自动提取到相应的二级域名信息,并根据二级域名获取到相应的数据。

 

再来说一下第二部分:

第一部分主要解决了http://netfork.iteye.com形式访问,但是,如果想实现http://netfork.iteye.com/blog/xxx形式也能正常路由,且不是redirect形式,就需要借助于ApplicationController的过滤器来实现。

  # 二级域名过滤
  before_filter :subdomain_filter

  # 二级域名过滤器
  def subdomain_filter
    subdomain_name = request.subdomains.first.to_s

    # 判断是否允许使用二级域名进行处理
    if subdomain_name != "www" && ["companies", "news", "msg", "user"].include?(controller_name)
      redirect_to request.url.to_s.sub(subdomain_name, "www")
      return false
    else
      params[:company_name] = subdomain_name
    end
  end

 

 

其实原理就是在过滤器中,将二级域名取出来,然后判断一下,此域名是否允许作为二级域名处理,如果不允许,则直接重定向至www开头的域名中,如果属于二级域名过滤的范围,就将二级域名设到params中,继续向后执行。

比如以下的域名:

http://netfork.hulian56.com/company/about

只需要在company控制器的about这个action中执行如下代码,即可获得netfork对应的about信息。

@company = Company.find_by_domain_name(params[:company_name])

 这样,就解决了以二级域名打头后面带着特定请求的问题了。

 

 

完。

 

分享到:
评论
8 楼 dch1287 2009-07-08  
首先要域名服务商支持泛域名定义吧
7 楼 netfork 2009-07-08  
酷!爽!
我的实现与老大的描述原理上大体相近,javaeye的完整实现思路印证了我的一些猜想,让我对自己实现的这部分代码有了信心。
再次向robbin致谢。
6 楼 robbin 2009-07-08  
  def blog?
    if request.subdomains && request.subdomains[0] && request.subdomains.length == 1 && !RESERVED_DOMAIN.include?(request.subdomains[0])
      @blog_owner ||= User.find_by_domain(request.subdomains[0])
      return !@blog_owner.nil?
    end
    return false
  end
  def group?
    if request.subdomains && request.subdomains[1] && request.subdomains[1].eql?("group") && request.subdomains.length == 2
      @group ||= Group.find_by_domain request.subdomains[0]
      return !@group.nil? && @group.active?
    end
    return false
  end


/blog/xxx 就是标准的Rails路由映射,只不过这种controller需要加一个filter去判断进来的域名,如果不是博客域名访问过来的话就要redirect。
  before_filter :blog_domain_required, :except => [:rss_blog, :show]
  def blog_domain_required
    redirect_to homepage_url and return false unless blog?
  end
5 楼 netfork 2009-07-08  
robbin 写道
二级域名支持是一个很简单的问题,把JavaEye的代码贴出来供你参考:

  # show website homepage
  def homepage
    if www?
      render :template => 'main/homepage', :layout => false
    elsif app?
      if logged_in?
        render :template => 'app/base/index', :layout => 'app'
      else
        redirect_to homepage_url
      end
    elsif job?
      render :template => 'job/homepage', :layout => 'job'
    elsif channel?
      @channel = request.subdomains[0]
      if File.exists?("#{RAILS_ROOT}/app/views/channel/#{@channel}/index.rhtml")
        render :template => "channel/#{@channel}/index", :layout => 'channel'
      else
        render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
      end
    elsif blog?
      @blogs = @blog_owner.blogs_by_page params[:page]
      render :template => 'blog/index/index', :layout => 'blog'
    elsif group?
      Group.increment_counter(:visit_count, @group.id)
      render :template => 'group/index/index', :layout => 'group'
    else
      redirect_to homepage_url
    end
  end


  protected
  def www?
    return request.subdomains && request.subdomains[0] && request.subdomains.length == 1 && request.subdomains[0] == 'www'
  end
  
  def job?
    return request.subdomains && request.subdomains[0] && request.subdomains.length == 1 && request.subdomains[0] == 'job'
  end

  def app?
    return request.subdomains && request.subdomains[0] && request.subdomains.length == 1 && request.subdomains[0] == 'app'
  end
  
  def channel?
    return request.subdomains && request.subdomains[0] && request.subdomains.length == 1 && RESERVED_DOMAIN.include?(request.subdomains[0])
  end


判断一下subdomains,根据不同的域名做不同的处理,就这么简单。

谢谢robbin老大的回复。
我的作法也是参考了你n年前的只言片语写的,这回算是有幸见着原装的了。
有一个问题,就是比较关键的 blog? 方法能放上来吗?
还有一个问题,就是如:http://netfork.iteye.com/blog/XXX这样的效果似乎上面的代码并没有给出实现方法吧。
4 楼 robbin 2009-07-08  
二级域名支持是一个很简单的问题,把JavaEye的代码贴出来供你参考:

  # show website homepage
  def homepage
    if www?
      render :template => 'main/homepage', :layout => false
    elsif app?
      if logged_in?
        render :template => 'app/base/index', :layout => 'app'
      else
        redirect_to homepage_url
      end
    elsif job?
      render :template => 'job/homepage', :layout => 'job'
    elsif channel?
      @channel = request.subdomains[0]
      if File.exists?("#{RAILS_ROOT}/app/views/channel/#{@channel}/index.rhtml")
        render :template => "channel/#{@channel}/index", :layout => 'channel'
      else
        render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
      end
    elsif blog?
      @blogs = @blog_owner.blogs_by_page params[:page]
      render :template => 'blog/index/index', :layout => 'blog'
    elsif group?
      Group.increment_counter(:visit_count, @group.id)
      render :template => 'group/index/index', :layout => 'group'
    else
      redirect_to homepage_url
    end
  end


  protected
  def www?
    return request.subdomains && request.subdomains[0] && request.subdomains.length == 1 && request.subdomains[0] == 'www'
  end
  
  def job?
    return request.subdomains && request.subdomains[0] && request.subdomains.length == 1 && request.subdomains[0] == 'job'
  end

  def app?
    return request.subdomains && request.subdomains[0] && request.subdomains.length == 1 && request.subdomains[0] == 'app'
  end
  
  def channel?
    return request.subdomains && request.subdomains[0] && request.subdomains.length == 1 && RESERVED_DOMAIN.include?(request.subdomains[0])
  end


判断一下subdomains,根据不同的域名做不同的处理,就这么简单。
3 楼 gokure 2009-07-04  
可以试试plug-in subdomain_fu.
http://github.com/mbleigh/subdomain-fu/tree/master
2 楼 netfork 2009-07-02  
night_stalker 写道
貌似在 httpd 配置比较好?

怎么配呢?
1 楼 night_stalker 2009-07-02  
貌似在 httpd 配置比较好?

搜到这个……
http://hideto.iteye.com/blog/204962

相关推荐

Global site tag (gtag.js) - Google Analytics