Ruby on Rails URL格式

时间:2012-11-19 13:30:07

标签: ruby-on-rails ruby

我有一个Ruby on Rails应用程序,您可以在其中创建“帖子”。我开始使用脚手架生成器来生成标题,这是一个字符串,正文是内容。

每个'post'都有一个id的url,例如/ 1,/ 2,/ 3等。

有没有办法将其更改为一串随机字符,例如/ 49sl,/ l9sl等?

更新

以下是posts_controller.rb

的内容
class PostsController < ApplicationController
  # GET /posts
  # GET /posts.json
  def index
    @posts = Post.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @posts }
    end
  end

  # GET /posts/1
  # GET /posts/1.json
  def show
    @post = Post.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @post }
    end
  end

  # GET /posts/new
  # GET /posts/new.json
  def new
    @post = Post.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @post }
    end
  end

  # GET /posts/1/edit
  def edit
    @post = Post.find(params[:id])
  end

  # POST /posts
  # POST /posts.json
  def create
   @post = Post.new(params[:post])

    respond_to do |format|
      if @post.save
        format.html { redirect_to @post, notice: 'Post was successfully created.' }
        format.json { render json: @post, status: :created, location: @post }
      else
        format.html { render action: "new" }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /posts/1
  # PUT /posts/1.json
  def update
    @post = Post.find(params[:id])

    respond_to do |format|
      if @post.update_attributes(params[:post])
        format.html { redirect_to @post, notice: 'Post was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /posts/1
  # DELETE /posts/1.json
  def destroy
    @post = Post.find(params[:id])
    @post.destroy

    respond_to do |format|
      format.html { redirect_to posts_url }
      format.json { head :no_content }
    end
  end
end

6 个答案:

答案 0 :(得分:15)

Rails使用ActiveRecord对象的to_param方法将其解析为URL。

假设您有办法生成这些唯一ID(将其称为IdGenerator),您可以执行以下操作:

1-每当你持久化Post对象并将其保存到数据库时生成这个id,让我们说在url_id列下

class Post < ActiveRecord::Base
  before_create :generate_url_id
  def generate_url_id
    self.url_id = IdGenerator.generate_id
  end
end

2-在Post模型中覆盖to_param方法:

class Post < ActiveRecord::Base
  def to_param
    return url_id
  end
end

现在post_path(@post)将解析为/ posts / url_id

顺便说一句,如果您还没有ID生成器,则可以使用SecureRandom.urlsafe_base64look here

详细了解documentation for to_param

答案 1 :(得分:2)

我希望这两种资源可以帮到你:

  1. 名为obfuscate_id的宝石。它以以下格式表示ID:

    http://tennisfans.eu/products/4656446465

  2. 另一颗宝石 - masked_id。它提供了类似的功能。您可以使用url创建的格式控制,在类中定义它。看看它出现的来源,这个gem使用了obfuscate_id gem的策略。

答案 2 :(得分:0)

在Erez手动方式旁边,您可以使用friendly_id gem,并使用唯一ID作为slug。

class Post < ActiveRecord::Base
  # FriendlyId
  friendly_id :uid

  # Set a unique user id on create
  before_save :set_uid, on: :create

  def set_uid
    self[uid] = rand(36**8).to_s(36)
  end
end

请注意,此处的uid设置无法确保唯一性。你当然需要添加一些验证,但整个主题与google不同。

答案 3 :(得分:0)

如果您想使用gem,那么Friendly_id是一个很好的解决方案。

关注此截屏视频:

http://railscasts.com/episodes/314-pretty-urls-with-friendlyid

(视频或asciicast,视情况而定)

Ryan Bates的截屏视频非常出色。

答案 4 :(得分:0)

如果您仍想要另一个ID生成选项,可以尝试使用UUID:

https://en.wikipedia.org/wiki/Universally_unique_identifier

和红宝石宝石很容易产生它们:

https://github.com/assaf/uuid

但是,我会问:为什么你想让它们随机?如果您正在尝试做什么 是为了避免你的一个用户在网址中输入另一个id并访问不属于他们的数据,那么你可能希望通过查找查找器来限制控制器中的访问,如下所示:

def show
    @post = current_user.posts.where(:id => params[:id]).first
    respond_to do |format|
       format.html # show.html.erb
       format.json { render json: @post }
    end
end

在这种情况下,current_user是一个函数,它返回当前经过身份验证的用户(来自会话或应用程序逻辑所指示的任何内容)。

答案 5 :(得分:0)

您可以按照以下3个步骤为帖子提供随机网址:

1-在您的模型(Post.rb)中,为每个帖子生成一个随机字符串,然后再保存。例如,

class Post < ActiveRecord::Base
  before_create :generate_url_id
  def generate_url_id
    self.url_id = SecureRandom.urlsafe_base64
  end
end

2-在您的模型(Post.rb)中,提供to_param method以覆盖Rails默认URL生成。例如:

class Post < ActiveRecord::Base
  def to_param
    self.url_id
  end
end

3-在你的控制器(PostsController.rb)中,使用动态查找器通过随机字符串查找帖子。例如,

class PostsController < ApplicationController
  def show
    @post = Post.find_by_url_id(params[:id])
    ...
  end
end

我继续把a complete example and posted it to Github放在一起。