Rails 4路由参数由关键字定义

时间:2016-01-23 12:24:29

标签: ruby-on-rails ruby routes

我们正在尝试设置rails路由,其参数之间的间隔大于正斜杠符号。

举个例子:

@IBAction func Move(sender: AnyObject) {
    let sectionInfo = self.fetchedResultsController.sections![1] 
    let objectsToMove = sectionInfo.objects as! [SList]
    for item in objectsToMove {
        let newItem = NSEntityDescription.insertNewObjectForEntityForName("SCList", inManagedObjectContext:self.managedObjectContext!) as! SCList
        newItem.scitem = item.slitem
        newItem.scqty = item.slqty
        newItem.scdesc = item.scdesc
        self.managedObjectContext.deleteObject(item)            
    }
    self.performSegueWithIdentifier("moveToSC", sender: self)
}

对于以下路径,我们希望提取SOME-ITEM和SOME-PLACE字符串作为参数,同时确定使用" -for-sale /"一部分。

我一直在玩someexample.com/SOME-ITEM-for-sale/SOME-PLACE 构造的变体但没有任何成功。我在正确的地方寻找吗?谢谢!

更新

最后我选择了这个解决方案:

:constraints => {:item => /[^\/]+/}

然后恢复了全部" SOME-ITEM-for-sale"使用

在控制器中进行解析
get ':type/*place' => 'places#index', as: :place , :constraints => {:type => /[^\/]+-for-sale/}

希望能帮助别人!

2 个答案:

答案 0 :(得分:1)

friendly_id就是你想要的:

#Gemfile
gem 'friendly_id', '~> 5.1.0'

$ rails generate friendly_id
$ rails generate scaffold item name:string slug:string:uniq
$ rake db:migrate

#app/models/item.rb
class Item < ActiveRecord::Base
   extend FriendlyId
   friendly_id :name, use: [:slugged, :finders]
end

以上内容会为您提供slug列,FriendlyId会查找您发送给应用的任何请求:

#config/routes.rb
resources :items, path: "" do
   resources :places, path: "" #-> url.com/:item_id/:id
end

虽然参数仍然是id(除非您使用resources FriendlyId,但slug将覆盖您的路线和模型以使用{{1}而是:

<%= link_to "Item Place", items_place_path(@item, @place) %> #-> url.com/item-name-information/place-name-information

<强>更新

如果你想拥有一个动态的&#34;路由结构,您将能够使用以下内容(这需要FriendlyId的{​​{3}}模块):

#config/routes.rb
#...
get '/:item_id/:place_id', to: SlugDispatcher.new(self), as: :item #-> this has to go at the bottom 

#lib/slug_dispatcher.rb
class SlugDispatcher

  #http://blog.arkency.com/2014/01/short-urls-for-every-route-in-your-rails-app/
  ##########################################

  #Init
  def initialize(router)
    @router = router
  end

  #Env
  def call(env)
    id     = env["action_dispatch.request.path_parameters"][:item_id]
    slug   = Slug.find_by slug: id
    if slug
      strategy(slug).call(@router, env)
    else
      raise ActiveRecord::RecordNotFound
    end
  end

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

  private

  #Strategy
  def strategy(url)
    Render.new(url)
  end

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

  #Render
  class Render

    def initialize(url)
      @url = url
    end

    def call(router, env)
      item        = @url.sluggable_type.constantize.find @url.sluggable_id
      controller  = (@url.sluggable_type.downcase.pluralize + "_controller").classify.constantize 
      action      = "show"
      controller.action(action).call(env)
    end

  end

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

end

这不会解决问题(我们尚未针对嵌套路线进行调整),但会为您提供路由到相应控制器的能力。

答案 1 :(得分:0)

最后我们采用了这个解决方案:

get ':type/*place' => 'places#index', as: :place , :constraints => {:type => /[^\/]+-for-sale/}

如果:type参数在字符串

中包含“-for-sale”,则仅激活router命令

然后我们恢复了完整的“SOME-ITEM-for-sale”sting,用于在控制器中解析

params[:type]

希望能帮助别人!