我正在开发一个应用程序,我将一个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(:姓名,:饥饿,:情绪)
我如何也允许:可爱的价值?
答案 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几乎可以将日志大小加倍...