考虑具有相似模式的多个路由(Rails 4)

时间:2014-08-07 07:35:34

标签: ruby-on-rails ruby ruby-on-rails-3 rails-routing

我怎么能算这个代码。我是一个Rails新手,并且知道应该可以干这个并考虑它:

MyApp::Application.routes.draw do 

match "/france",          to: 'static_pages#set_france_in_session_and_redirect',          via: 'get'
match "/germany",         to: 'static_pages#set_germany_in_session_and_redirect',         via: 'get'
match "/unitedstates",    to: 'static_pages#set_us_in_session_and_redirect', path: 'us',  via: 'get'
match "/andsoon.....",    to: 'static_pages#set_us_in_session_and_redirect', path: 'us',  via: 'get'

end

我将在大约20个国家/地区使用它,我不能将其考虑在内,以便不要有20行代码吗?

修改

#####################################

根据所有有见解的答案/建议(谢谢!),我认为我没有提供足够的背景和信息来实现我的目标。所以我会在这里给出更多见解,因为由于我缺乏相关信息,答案无法回答我想做的事情。

以下是此交易:我正在尝试构建每日交易Rails应用。

我有一个名为http://myapp.com的主页

感谢IP检测(geocoder gem),当法国用户加载主页时,他到达http://myapp.com,我只显示法国人的内容(法国居民的交易)。

现在,用户可以转到名为http://myapp.com/global的页面,并根据需要选择其他国家/地区:见下文

enter image description here

如果他点击"德国",这基本上做了两件事:

  1. 设置会话[:country] =德国
  2. 然后将他重定向到主页myapp.com(但德国'现在存储在会话中,所以我只能向他展示德国居民的交易')
  3. 我有一个BIG约束,我知道它不是很Rails-way但是肯定希望保持这样:我希望访问者在浏览器中看到的URL始终为{{ 3}}和NOT http://myapp.comhttp://myapp.com/france等等......

    这就是为什么我不能像一个人建议的那样使用params session [:counrty] = params [:country]

    确实,使用params [:country]会导致创建http://myapp.com/germanyhttp://myapp.com/country=germany等网址(也许我也是新手,但我无法使其工作,并使用参数虽然只有一个主页的网址显示为http://myapp.com/germany

    所以"技巧"我发现哪些不是Rails-way,我知道它不是面向对象的如下:

    页面http://myapp.com

    <p>
    <%= link_to "MyApp France", france_path, 
                confirm: "Are you sure you want to switch to MyApp France?" %><br/>
    <%= link_to "MyApp  Germany", germany_path,
                confirm: "Are you sure you want to switch to MyApp Germany? " %><br/>
    <%=  link_to "MyApp  US", unitedstates_path,
                confirm: "Are you sure you want to switch to MyApp US? " %>  
    </p>
    

    然后,一旦他们点击此链接(例如德语链接),访问者就会被发送到 我创建了一条路线的germany_path:

      match "/france",          to: 'static_pages#set_france_in_session_and_redirect',          via: 'get'
      match "/germany",         to: 'static_pages#set_germany_in_session_and_redirect',         via: 'get'
      match "/unitedstates",    to: 'static_pages#set_us_in_session_and_redirect', path: 'us',  via: 'get'
    

    static_pages #set_germany_in_session_and_redirect指向/app/controllers/static_pages_controller.rb:

    # Enable not logged-in user to choose country version in the page/global)
      def set_france_in_session_and_redirect
        session[:country] = "France"
        redirect_to_root
      end
    
    
      def set_germany_in_session_and_redirect
        session[:country] = "Germany"
        redirect_to_root
      end
    
      def set_us_in_session_and_redirect
        session[:country] = "United States"
        redirect_to_root
      end
    

    显然,它不是Rails方式,我想改进它,向你们学习,但我不知道该怎么做。

    你能帮助我做到这一点,但是用一种更好的Rails方式,清洁和正确吗?

2 个答案:

答案 0 :(得分:3)

好像你只为设置一个会话变量做了20个不同的操作。因此,结合所有操作并进行一个操作并在参数中发送国家/地区信息/名称,并在会话中设置并适当地重定向。

def set_countries_session
  session[:counrty] = params[:country]
  redirect 'your path'
end

如果您仍然希望采用20个操作的方法,那么您可以使用一系列国家/地区重构您的路线代码

['germany', 'france', 'so on'].each do |country|
  match "/#{country}", to: "static_pages#set_#{country}_in_session_and_redirect",  via: 'get'
end

答案 1 :(得分:2)

<强>路线

滑轨&#39;路由结构是围绕resources构建的,它基于Ruby的object-orientated性质(Rails构建的语言)

简单地说,您的路线应该反映您希望填充的对象,而不是&#34;功能&#34;你希望实现。开始时它有点令人头疼,但是一旦你意识到它是如何工作的,它就会变得简单得多:

#config/routes.rb
resources :static_pages, only: :show, path: "", as: :country #-> domain.com/:id

这是传统的&#34; Rails将为您提供路径的方式。虽然不可否认,它不会给你[country]_path帮助,但保持你的代码超级干净(如下所示)


<强>控制器

您的问题出在您的控制器上,您需要在路由修复之前解决这个问题。

真正的问题是您正在使用20种不同的控制器操作。是面向对象吗?不。

我这样做:

#app/controllers/static_pages_controller.rb
Class StaticPagesController < ApplicationController
   def show
       country = params[:id]
       ... business logic
   end
end

这样,您就可以在单country次操作中尽可能多地使用show变量。此面向对象,因为show操作将显示您的static_page


<强>蛞蝓

为了获得"sluggable" URL能力,您最好使用friendly_id gem

#app/models/your_model.rb
Class Model < ActiveRecord::Base
   friendly_id :column, use: [:slugged, :finders]
end

这使您能够将country对象用作slug而不是id

#view
<%= link_to "France", country_path("france") %>