我有一个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
答案 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_base64
或look here。
答案 1 :(得分:2)
我希望这两种资源可以帮到你:
名为obfuscate_id的宝石。它以以下格式表示ID:
另一颗宝石 - 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
和红宝石宝石很容易产生它们:
但是,我会问:为什么你想让它们随机?如果您正在尝试做什么 是为了避免你的一个用户在网址中输入另一个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