简体   繁体   English

Rails:什么决定了传递的“params”的名称?

[英]Rails: What determines name of "params" passed?

So I can't quite find the answer on the internet for this seemingly simple problem.所以我在互联网上找不到这个看似简单的问题的答案。

What I've gone through tutorial apps, for say a basic CRUD app...and lets say your normal User create/edit/update/delete pages.我经历过的教程应用程序,比如说一个基本的 CRUD 应用程序......让我们说你的普通用户创建/编辑/更新/删除页面。

Typically you see something like:通常,您会看到类似以下内容:

params.require(:user).permit(:name, :email, :password, :password_confirmation)

So this means the params passed is params(:user) right?所以这意味着传递的参数是params(:user)对吗?

However sometimes, such as when doing a link_to and passing something to to a POST request (Such as a patch or update or something similar) the param is simply params[:id] .但是有时,例如在执行link_to并将某些内容传递给 POST 请求(例如补丁或更新或类似内容)时,参数只是params[:id] What determines what the params(:<name>) is going to be called?什么决定了params(:<name>)将被称为什么?

It seems to be dependent on forms...but sometimes not?它似乎取决于形式……但有时不是? Does it just default to id otherwise or something?它是否只是默认为id或其他什么?

Rails guide mentions this Rails 指南提到了这一点

params is combination of: params是以下各项的组合:

  1. routing parameters路由参数
  2. GET-parameters ( example.org/page?some_param=value ) GET 参数( example.org/page?some_param=value
  3. POST parameters (form data, decoded json, etc.) POST 参数(表单数据、解码后的 json 等)

params[:id] usually comes from routing parameters ( /users/:id ), there can be other route params (for example other common case is nested routes like /users/:user_id/some_other_resources/:id - there will be :user_id and :id ) and by convention saved object is passed in params[:model_name] params[:id]通常来自路由参数( /users/:id ),可以有其他路由参数(例如其他常见情况是嵌套路由,如/users/:user_id/some_other_resources/:id - 会有:user_id:id ) 并且按照约定保存的对象在params[:model_name]传递

Parameters are part of HTTP requests.参数是 HTTP 请求的一部分。 HTTP requests have no restrictions on what can be sent as a parameter (outside of size of data being sent). HTTP 请求对可以作为参数发送的内容没有限制(在发送的数据大小之外)。 So, you can send a request to any route on your server with params.因此,您可以使用参数向服务器上的任何路由发送请求。

Rails attempts to prevent any evil, sneaky, people from injecting parameters and values where they don't belong. Rails 试图阻止任何邪恶的、鬼鬼祟祟的人在不属于他们的地方注入参数和值。 We can do that by creating a method that wraps our params object in a specified structure:我们可以通过创建一个将 params 对象包装在指定结构中的方法来做到这一点:

params.require(:user).permit(:name, :email, :password, :password_confirmation)

This means params must be sent in this format:这意味着必须以这种格式发送params

user: {
  name: "name",
  password: "password",
  password_confirmation: "password"
}

If you check your logs in development, Rails will display your params (should any be sent) in each request.如果您在开发中检查日志,Rails 将在每个请求中显示您的参数(应该发送)。 If your params are not in that format (with a user at the root level) and you use the method user_params , it will throw an error.如果您的参数不是那种格式(用户处于根级别)并且您使用了user_params方法,它将引发错误。 user is required . user必需的 And should someone send the parameters:并且应该有人发送参数:

user: {
  name: "name",
  pseudonym: "sneaky param",
  password: "password",
  password_confirmation: "password"
}

Rails will still accept name , password , and password_confirmation , but it will reject pseudonym because it is not permitted by your method user_params . Rails 仍会接受namepasswordpassword_confirmation ,但它会拒绝pseudonym因为您的方法user_params不允许这样user_params

You'll see in a lot of code, people grab the params[:id] value directly.你会在很多代码中看到,人们直接获取params[:id]值。 That's because we're often only using that to read or destroy an item.那是因为我们通常只使用它来读取或销毁项目。 *_params methods are usually reserved for CREATE and UPDATE actions in the controller because that's where we are injecting params. *_params方法通常保留用于控制器中的 CREATE 和 UPDATE 操作,因为这是我们注入参数的地方。

It's not technically necessary.这在技术上是没有必要的。 Rails is already sanitizing user input in the Active Record queries. Rails 已经在 Active Record 查询中清理用户输入。 So, it's not a direct requirement for a secure app.因此,这不是安全应用程序的直接要求。 You could pull the params directly from the params hash, rather than using this method.您可以直接从 params 哈希中提取参数,而不是使用此方法。 But it certainly keeps your code DRY.但它肯定会让你的代码保持干燥。 It also ensures you're not giving user's access to important metadata in your model.它还确保您不会授予用户对模型中重要元数据的访问权限。 For example, if you're SO, you might (though unlikely) have an upvote column for my post.例如,如果您是 SO,您可能(虽然不太可能)为我的帖子设置一个 upvote 列。 If you whitelist all params and just accept all params into the Post.update(params) method, I could send a POST request with the params upvotes: 1,000,000 .如果您将所有参数列入白名单并仅将所有参数Post.update(params)方法中,我可以发送带有 params upvotes: 1,000,000POST请求。 I don't think they'd like that at all.我不认为他们会喜欢那样。

It can be determined by the route, by the input tag or by you.它可以由路线、输入标签或您来确定。

By the route:按路线:

rails routes -g user 
   Prefix Verb   URI Pattern               Controller#Action
   signup GET    /signup(.:format)         users#new
    users GET    /users(.:format)          users#index
          POST   /users(.:format)          users#create
edit_user GET    /users/:id/edit(.:format) users#edit
     user GET    /users/:id(.:format)      users#show
          PATCH  /users/:id(.:format)      users#update
          PUT    /users/:id(.:format)      users#update
          DELETE /users/:id(.:format)      users#destroy

Here, params[:id] is set by the url helper like edit_user_path(@user) .在这里, params[:id]由 url helper 设置,如edit_user_path(@user) You can set your own param name in config/routes.rb :您可以在config/routes.rb设置您自己的参数名称:

get 'profile/:user_id', to: 'users#show'
rails routes -g profile 
Prefix Verb URI Pattern                 Controller#Action
       GET  /profile/:user_id(.:format) users#show

By the input:通过输入:

<%= form_for @user... do |f| %>
  <%= f.text_field :name
<% end %>

Here, the form sets params: {user: {name: some_value}} , because the model object used by the form is User and the column name is name .这里,表单设置params: {user: {name: some_value}} ,因为表单使用的模型对象是User ,列名是name

And by you:由你:

link_to 'Profile', user_path(@user, locale: 'en')

which outputs: <a href=\\"/users/1?locale=en\\">Profile</a>输出: <a href=\\"/users/1?locale=en\\">Profile</a>

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

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