2015-09-25 202 views
0

我正在處理一個應用程序,在該應用程序中,我發送的請求以我的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

回答

0

你最好在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" 
0

這是到一些所謂的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) 
0

@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幾乎可以將日誌大小加倍...