rails如何解析POST请求参数?

时间:2015-09-25 18:19:12

标签: ruby-on-rails json ruby-on-rails-4 post parameters

我正在开发一个应用程序,我将一个post请求发送到我的rails服务器,参数以JSON格式存储。让我们说我的应用程序将请求路由到我的cats_controller上的create函数。猫模型有三个字段:名称,:饥饿,:情绪。现在每只猫都有很多小猫。我的小猫模型有两个字段:cat_id(指的是哪只猫拥有它,因为我的小猫属于一只猫)和:可爱。现在,每当我在我的应用程序上创建一个猫时,我想通过一次调用来完成它,所以我通过POST请求从我的应用程序调用/cats.json。参数以JSON格式存储,它们包括以下字段{name:"",饥饿:"",心情:"",可爱:& #34;"}。现在控制器使用这些参数创建一个新的cat,然后使用cat.kittens.build()创建一个分配给这只猫的新小猫。小猫然后只需要使用我发送的最后一个参数"心情:"正确创建。

现在的问题是,当我从这个控制器打印params变量时,我得到以下哈希:{name:"",饥饿:"",心情:& #34;",可爱:"",猫:{名字:"",饥饿:"",心情:" "}}。为什么会这样? Rails如何解析POST请求参数并带我从

{姓名:&#34;&#34;,饥饿:&#34;&#34;,心情:&#34;&#34;,可爱:&#34;&#34;} 至 {姓名:&#34;&#34;,饥饿:&#34;&#34;,心情:&#34;&#34;,可爱:&#34;&#34;,猫< / strong>:{姓名:&#34;&#34;,饥饿:&#34;&#34;,心情:&#34;&#34;}}

这是怎样的&#34; &#34;哈希生成,何时以及遵循什么规则?

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

params.require(:猫).permit(:姓名,:饥饿,:情绪)

我如何也允许:可爱的价值?

3 个答案:

答案 0 :(得分:1)

这取决于名为parameter wrapping

的内容

这是为了方便您不必提交根(即在您的情况下将所有内容放在用户元素中)但仍然可以使用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)

答案 1 :(得分:0)

您最好阅读HTTP - Difference between GET and POST

发送请求的不是 Rails ,它是普通的旧HTML。

您正在考虑的差异是您的服务器如何选择POST参数,考虑GET参数通过网址传递...

  

请注意,查询字符串(名称/值对)是在 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?

这应该可以让你创建一只猫,并让他/她被指定为另一只猫的小猫

#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"

答案 2 :(得分:0)

@Frederick Cheung:非常感谢这个链接。就像@Curse一样,我一直试图弄清楚为什么我会在rails日志中打印出我的JSON HTTP POST参数的两个副本(即:重复)。添加

wrap_parameters format: []

在我的控制器定义的顶部给了我

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

在我的日志输出中而不是

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

因为我意识到我有

wrap_parameters format: [:json]

在config / initializers / wrap_parameters.rb中。如果将大型JSON文档发布到Rails 3服务器,启用wrap_parameters几乎可以将日志大小加倍...