简体   繁体   English

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

[英]Change Params[:id] in Ruby on Rails

I have a Ruby on Rails application where you can create 'posts'. 我有一个Ruby on Rails应用程序,您可以在其中创建“帖子”。 I started of by using the scaffold generator to give generate the title which is a string and the body which is the content. 我开始使用脚手架生成器来生成标题,这是一个字符串,而主体是内容。

Each 'post' has a url of the id, for example /1, /2, /3, etc. 每个'post'都有一个id的url,例如/ 1,/ 2,/ 3等。

Is there a way to change it to generater a string of random characters and numbers, for example /49slc8sd, /l9scs8dl, etc? 有没有办法改变它来生成一串随机字符和数字,例如/ 49slc8sd,/ l9scs8dl等?

Here is what I have for the posts_controller.rb 这是我对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

And here is what I have in the post.rb model 这是我在post.rb模型中的内容

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

If you want your models not to have their primary key id in a predictable sequence, you can generate the id based on uuid or guid with the help of something like http://codesnipers.com/?q=using-uuid-guid-as-primary-key-in-rails 如果你希望你的模型不能以可预测的顺序获得他们的主键id,你可以在http://codesnipers.com/?q=using-uuid-guid-的帮助下基于uuid或guid生成id。 作为原色的键合导轨

However you can also route based on any other property which uniquely identifies the resource which is the recommended approach if in case you dont want to expose the database identifiers in your routes 但是,如果您不希望在路由中公开数据库标识符,您还可以基于唯一标识资源的任何其他属性进行路由,这是推荐的方法。

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

In your controller's action you can say 你可以说,在你的控制器的行动中

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

to get the Person object 获取Person对象

如果你想混淆数字ID,你可以看看这个有趣的讨论

You should also be aware of the to_param method for ActiveRecord::Base objects. 您还应该了解ActiveRecord :: Base对象的to_param方法。

Basically, Rails calls this method on your objects to know what to put in the URL and params[:id]. 基本上,Rails在你的对象上调用这个方法来知道在URL和params [:id]中放入什么。 By default it is just the primary key of the record in the database. 默认情况下,它只是数据库中记录的主键。 Say you override it as such: 假设你这样覆盖它:

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

The first record in your database would have url /posts/100 . 数据库中的第一条记录将包含url /posts/100

In your controller, to retrieve the object you just do 在您的控制器中,检索您刚刚执行的对象

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

(Of course you could override the default find method as well, but that is probably frowned upon.) Basically the to_param method transforms your id and the new finder undoes it. (当然你也可以覆盖默认的find方法,但这可能to_param 。)基本上, to_param方法会转换你的id,而新的finder会撤消它。 Usually you just point to another database column that has been automatically populated via a hook when the record is created. 通常,您只需指向另一个数据库列,该列在创建记录时已通过挂钩自动填充。 This is what is described in the link posted by Qumara otBurgas. 这是Qumara otBurgas发布的链接中描述的内容。

It's not clear what you are asking here. 目前尚不清楚你在这里问的是什么。 The path to the action specified in the routes does not require the id passed to be of a certain format. 路由中指定的操作的路径不要求传递的id为特定格式。 You can pass non-numeric ids if you want and within your action use the id however you'd like. 如果需要,您可以传递非数字ID,并且在您的操作中使用您想要的ID。 Maybe if you supplied more info about the routes and actions we could understand what you are asking for. 也许如果您提供了有关路线和行动的更多信息,我们可以理解您的要求。

There is a number of ways how you can generate a random string in Ruby. 多种方法可以在Ruby中生成随机字符串。

Now, to the second part of your question. 现在,问题的第二部分。 If you want to access your posts using a route like /post/rndm5tr , you can simply change this line of code inside your controller: 如果您想使用/post/rndm5tr这样的路径访问帖子,只需更改控制器内的这行代码即可:

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

to

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

Now, simply create a migration: rails g migration AddRandomnessToPost randomness:string and run rake db:migrate (or bundle exec rake db:migrate , depending on how it's set up). 现在,只需创建一个迁移: rails g migration AddRandomnessToPost randomness:string并运行rake db:migrate (或bundle exec rake db:migrate ,具体取决于它的设置方式)。

Of course, you are free to name the field whatever you want, randomness is just a random name I used. 当然,您可以随意命名字段, randomness只是我使用的随机名称。 I think the common convention is to call them slugs or tokens, but I might be wrong. 我认为常见的惯例就是称它们为slu or或代币,但我可能错了。

Now, add a method to before_create in your model to generate the random string and add it to the soon-to-be-saved Post object (using one of the examples from the above link). 现在,在模型中添加一个方法before_create以生成随机字符串,并将其添加到即将保存的Post对象中(使用上面链接中的一个示例)。 It would be wise to check if the string you're generating is already taken (you could write a recursive method that calls itself again if a post already has the random token). 检查你正在生成的字符串是否已经被采用是明智的(你可以编写一个递归方法,如果一个帖子已经有了随机标记,它会再次自我调用)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM