使用数据库中的值路由URL?

时间:2012-06-09 14:01:28

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

我有一个控制器streams_controller和一个模型streams

class StreamsController < ApplicationController
  def new
    @stream = Stream.new
  end

  def create
    @stream = Stream.new(params[:stream])
    if @stream.save
        flash[:success] = "Welcome!"
        redirect_to @stream
    else
        render 'new'
    end
  end


  def show
    @stream = Stream.find(params[:id])
  end
end

class Stream < ActiveRecord::Base
    attr_accessible :name, :email, :password, :password_confirmation
    before_save { |stream| stream.name = name.downcase }

    has_secure_password
.
.
.

基本上要使用show方法,我必须转到localhost/streams/[id],其中[id]是特定Stream的id。是否可以将URL重新路由为:localhost/[name]其中[name]是:Stream模型的:name属性?

因此,每次创建新Stream时,基本上都会创建一个新URL,它将对应于数据库中Stream的名称。

我将如何实施此目标?

无论如何,任何帮助或想法都非常感谢!

3 个答案:

答案 0 :(得分:2)

match '/:name' => 'streams#show'会给你params [:name]并路由到流中的show动作。如果与控制器名称发生冲突,则可以将此行放在routes.rb文件的末尾,以使相应的控制器操作优先。当然,最好确保这些冲突首先不会发生。

答案 1 :(得分:1)

我会尽可能地缩短网址的streams部分,但不要为空(以避免在仅使用名称而不是使用ID的情况下发生冲突)。

resources :streams, path: 's'

网址/s/stream-a不是那么大的妥协。

关于在网址中使用名称而不是ID,请参阅this Railscast

答案 2 :(得分:0)

您可以在路线中加载流。例如:

begin
  streams = Streams.all.map{|s| s.slug}
  match '/:stream' => 'streams#show', :stream => Regexp.new( "(#{streams.join('|')})" )
rescue Exception => e
  logger = Logger.new STDOUT
  logger.warn e.message
end

注意,我使用的是slug而不是名字 - 在这里使用安全的词语非常重要。因此,您可以根据流的slug创建name。此外,他们不应该覆盖其他路线。