Rails如何解析POST请求参数?

问题描述:

我正在处理一个应用程序,在该应用程序中,我发送的请求以我的Rails服务器参数存储在JSON格式中。假设我的应用程序将请求路由到我的cats_controller上的create函数。猫模型有三个字段:名称,饥饿,心情。现在每只猫都有一些小猫。我的小猫模型有两个字段:cat_id(指的是猫拥有它,因为我的小猫属于猫)和:可爱。现在,每次我在应用程序上创建一个猫时,我都希望通过一次调用完成它,所以我使用POST请求从我的应用程序调用/cats.json。参数以JSON格式存储,它们包括以下字段{name:“”,hunger:“”,mood:“”,cute:“”}。现在控制器使用这些参数创建一个新的猫,然后使用cat.kittens.build()创建一个分配给这个猫的新猫。然后,小猫只需要使用我发送的“心情:”的最后一个参数来正确创建。Rails如何解析POST请求参数?

现在的问题是,当我从这个控制器打印params变量时,我得到了以下哈希:{name:“”,hunger:“”,mood:“”,cute:“”,cat:{name :“”,饥饿:“”,心情:“”}}。为什么会发生? 如何Rails的解析POST请求参数,并把我从

{名: “” 饥饿 “” 心情: “” 可爱: “”} 到 {名: “” 饥饿” ”心情: “” 可爱: “” :{名称: “” 饥饿 “” 心情: “”}}

这是如何 “” 哈希生成的时候,它遵循什么规则?

然后,我的后续问题将是,因为在使用它们之前,rails 4会强制您将参数列入白名单。我做:

params.require(:CAT).permit(:名称,:饥饿:心情)

我怎么还允许:可爱的价值?

+0

您可以通过简单修改已有的代码来接受参数params.require(:cat ).permit(:name,:hunger,:mood,:cute)' – HolyMoly

+0

如果你在你的问题中包含你的代码是很有帮助的,因为它可以让人们更容易地看到发生了什么。我建议你发布你的控制器和表格(如果有的话)以及任何其他相关的代码。我不知道你在创建时如何输入猫的值,或者如何(通过表单),但我怀疑问题在那里,可能是语法。 – HolyMoly

+0

所以我找到的解决方案是从params.require(:cat).permit(:name,:hunger,:mood)中删除** require()**部分,然后只需将:cute添加到permit函数。 我的问题仍然存在,为什么在这种情况下会生成cat:属性。 当我从消息属性开始: {name:“”,hunger:“”,mood:“”,cute:“”} 为什么rails会将它们转换为: {name:“”,hunger:“ “,心情:”“,可爱:”“,猫:{名称:”“,饥饿:”“,心情:”“}} ”cat:{name:“”,hunger:“” :““}“ 来自? – Curse

你最好在HTTP - Difference between GET and POST上阅读。


这不是Rails的其发送请求,这是普通的老HTML。

你看是你的服务器如何拿起POST参数,可以考虑GET PARAMS通过URL传递的区别...

注意查询字符串(名称/值对)被发送在一个的URL的GET 请求:

注意,查询字符串(名称/值对)在HTTP消息被发送一个POST请求的 体

因此,您的问题的基本级别答案是,您需要将POST参数附加到请求的消息正文。我知道如何做到这一点的最好的例子是使用jQuery的ajax:

$.ajax({ 
    url: ..., 
    data: {your: key, value: pairs} 
}); 

为了回答您的其他问题,这里的结构,你应该使用:

#app/models/cat.rb 
class Cat < ActiveRecord::Base 
    #columns id | name | mood | created_at | updated_at 
    has_and_belongs_to_many :kittens 
      class_name: "Cat", 
      join_table: :kittens, 
      foreign_key: :cat_id, 
      association_foreign_key: :kitten_id 
    alias_attribute :born, :created_at #-> allows you to call @cat.born 
end 

#kittens table 
#columns cat_id | kitten_id 

你可以约读了自己加入这里:Rails: self join scheme with has_and_belongs_to_many?

这应该给你创建一只猫的能力,并将他/她分配为另一个ca的小猫 T:

#app/controllers/cats_controller.rb 
class CatsController < ApplicationController 
    def new 
     @cat = Cat.new 
    end 
    def create 
     @cat = Cat.new cat_params 
     @cat.save 
    end 

    private 

    def cat_params 
     params.require(:cat).permit(:name, :mood, :kittens) 
    end 
end 

这将使你具备以下能力:

#app/views/cats/new.html.erb 
<%= form_for @cat do |f| %> 
    <%= f.text_field :name %> 
    <%= f.text_field :mood %> 
    <%= f.collection_select :kittens, Cat.all, :id, :name %> 
    <%= f.submit %> 
<% end %> 

这也将让您致电:

@cat = Cat.find params[:id] 
@cat.kittens.each do |kitten| 
    kitten.mood #-> "cute" 

这是到一些所谓的parameter wrapping

它在那里作为一种便利,所以你不必提交根(即在你的情况下,p ut仍然可以使用)但仍可以使用params[:user]

默认情况下,如果您有请求格式的参数打包,则CatsController将为匹配Cat.attribute_names的任何参数执行此操作。可以自定义参数包装是如何用于控制器完成(或将其关闭,在控制哪些内容类型触发它)与wrap_parameters方法,例如

class CatsController < ActionController::Base 
    wrap_parameters :cat, include: [:cute] 
end 

也包括在参数列表中的可爱包装,然后你可以做

params.require(:cat).permit(:name, :hunger, :mood, :cute) 

@Frederick祥:谢谢你这么多的链接。就像@Curse一样,我一直在弄清楚为什么我会在rails日志中打印出我的JSON HTTP POST参数的两个副本(即:重复)。在我的日志输出在我的控制器定义顶部添加

wrap_parameters format: [] 

给我

{name:"",hunger:"", mood:"",cute:""} 

,而不是

{name:"", hunger:"", mood:"", cute:"", cat:{name:"", hunger:"", mood:""}} 

,因为我意识到我有

wrap_parameters format: [:json] 

配置/初始化/ wrap_parame ters.rb.如果将大型JSON文档发布到Rails 3服务器,启用wrap_parameters几乎可以将日志大小加倍...