在Ruby on Rails中更改Params [:id]

时间:2012-11-23 19:38:59

标签: ruby-on-rails ruby

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

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

有没有办法改变它来生成一串随机字符和数字,例如/ 49slc8sd,/ l9scs8dl等?

以下是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

以下是我在post.rb模型中的内容

class Document < ActiveRecord::Base
  attr_accessible :content, :name
end

5 个答案:

答案 0 :(得分:1)

如果您希望您的模型不能以可预测的顺序拥有其主键ID,您可以借助http://codesnipers.com/?q=using-uuid-guid-as-primary-key-in-rails

之类的帮助基于uuid或guid生成id

但是,如果您不希望在路由中公开数据库标识符,您也可以根据唯一标识资源的任何其他属性进行路由,如果您不希望在路由中公开数据库标识符

person/:person_random_token, :controller => :persons, :action => :show #adding this in your route file directing to the controller where you can use params[:person_random_token] to uniquely identify your person object in Persons model

在控制器的操作中,您可以说

Person.find_by_random_token(params[:person_random_token]) #assuming random_token is your column name

获取Person对象

答案 1 :(得分:1)

如果您想混淆数字ID,可以查看this interesting discusion

答案 2 :(得分:1)

您还应该了解ActiveRecord :: Base对象的to_param方法。

基本上,Rails在你的对象上调用这个方法来知道在URL和params [:id]中放入什么。默认情况下,它只是数据库中记录的主键。假设你这样覆盖它:

class Post < ActiveRecord::Base

  def to_param
    return id*100
  end

  def self.find_by_new_id(n)
    return self.find(n/100) # really you'd want to handle strings and integers
  end
end

数据库中的第一条记录将包含网址/posts/100

在您的控制器中,检索您刚刚执行的对象

@post = Post.find_by_new_id(params[:id])

(当然你也可以覆盖默认的find方法,但这可能不赞成。)基本上to_param方法会转换你的id,新的finder会撤消它。通常,您只需指向另一个数据库列,该列在创建记录时已通过挂钩自动填充。这就是Qumara otBurgas发布的链接中描述的内容。

答案 3 :(得分:0)

目前尚不清楚你在这里问的是什么。路由中指定的操作的路径不要求传递的id为特定格式。如果需要,您可以传递非数字ID,并且在您的操作中使用您想要的ID。也许如果您提供了有关路线和行动的更多信息,我们可以理解您的要求。

答案 4 :(得分:0)

a number of ways如何在Ruby中生成随机字符串。

现在,问题的第二部分。如果您想使用/post/rndm5tr等路线访问帖子,只需在控制器中更改此行代码即可:

@post = Post.find(params[:id])

@post = Post.find_by_randomness(params[:id])

现在,只需创建一个迁移:rails g migration AddRandomnessToPost randomness:string并运行rake db:migrate(或bundle exec rake db:migrate,具体取决于它的设置方式。)

当然,您可以随意命名字段,randomness只是我使用的随机名称。我认为常见的惯例就是称它们为slu or或代币,但我可能错了。

现在,在模型中为before_create添加一个方法,以生成随机字符串,并将其添加到即将保存的Post对象中(使用上述链接中的一个示例) )。检查你正在生成的字符串是否已经被采用是明智的(你可以编写一个递归方法,如果帖子已经有随机标记,它会再次调用自己。)