Rails 4未允许的参数 - JSON数据

时间:2015-05-08 23:55:38

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

我正在开发使用Google定义API的AngularJS和Rails应用。 API返回JSON响应。

我想将JSON响应存储在Words表中。我通过Angular控制器发出API请求,然后我尝试将数据添加到Words表中。

我得到了一个"未经许可的参数"我尝试插入JSON数据时出错。我已经研究过,这似乎是由于Rails 4 nested params

我尝试在Words控制器中为word_params方法添加嵌套括号,但后来得到"未经许可的参数:dataType,numToShow,groupNumber,groupResult,sectionType,dictionary" ...这是API响应。

是否有更简单的方法来允许完整的JSON数据而无需在控制器的word_params方法中专门定义每个嵌套参数?

scheme.rb

create_table "words", force: :cascade do |t|
  t.string   "title"
  t.json     "full_data"
  t.integer  "list_id"
  t.datetime "date"
end

Word控制器

class WordsController < ApplicationController
respond_to :json

def create
  list = List.find(params[:list_id])
  word = list.words.create(word_params)
  respond_with list, word
end

private
def word_params
  params.require(:word).permit(:title, :date, :full_data => {})
end

end

app.js

//= require angular-rails-templates
//= require_tree .

angular.module('d-angular', ['ui.router', 'templates'])

// Set routing/configuration
// ------------------------------
.config(['$stateProvider', '$urlRouterProvider',

    // Set state providers
    function($stateProvider, $urlRouterProvider) {$stateProvider

        // Home state
        .state('home', {
          url: '/home',
          templateUrl: 'home.html',
          controller: 'MainCtrl',
          resolve: {
              listPromise: ['lists', function(lists){
                return lists.getAll();
              }]
          }
        })

        // Lists state
        .state('lists', {
          url: '/lists/{id}',
          templateUrl: 'list.html',
          controller: 'ListsCtrl',
            resolve: {
              list: ['$stateParams', 'lists', function($stateParams, lists) {
                return lists.get($stateParams.id);
              }]
            }
        })

        $urlRouterProvider.otherwise('home');
    }
])


// lists factory
// Factories are used to organize and share code across the app.
// ------------------------------
.factory('lists', ['$http',

    function($http){
        // create new obect with array of lists
        var o = { lists: [] };

        // get all lists
        o.getAll = function() {
            return $http.get('/lists.json').success(function(data){
                angular.copy(data, o.lists);
            });
        };

        // get specific list
        o.get = function(id) {
          return $http.get('/lists/' + id + '.json').then(function(res){
            return res.data;
          });
        };

        // create list
        o.create = function(post) {
          return $http.post('/lists.json', post).success(function(data){
            o.lists.push(data);
          });
        };

        // add word to list
        o.addWord = function(id, word) {
          return $http.post('/lists/' + id + '/words.json', word);
        };

        return o;

    }
])

// Lists controller
// ------------------------------
.controller('ListsCtrl', ['$scope', 'lists', 'list', '$http',

    // Main scope (used in views)
    function($scope, lists, list, $http){

        $scope.list = list;             // get list by ID

        // Add word function
        $scope.addWord = function(){

            // API URL
            var api_url = "https://www.googleapis.com/scribe/v1/research?key=AIzaSyDqVYORLCUXxSv7zneerIgC2UYMnxvPeqQ&dataset=dictionary&dictionaryLanguage=en&query=";

            // get data from API
            $http.get(api_url + $scope.title)

                // handle successful api request
                .success(function (response) {

                    // push new word to array
                    lists.addWord(list.id, {
                        title: $scope.title,
                        date: new Date().toJSON().slice(0,10),
                        full_data: response
                    })
                    .success(function(word) {
                        $scope.list.words.push(word);
                    });
                });

        };

    }

]);

控制台响应

Started POST "/lists/1/words.json" for ::1 at 2015-05-08 19:53:11 -0400

    Processing by WordsController#create as JSON
      Parameters: {"title"=>"fallacy", "date"=>"2015-05-08", "full_data"=>{"dataType"=>"dictionary", "numToShow"=>1, "groupNumber"=>0, "groupResult"=>{"query"=>"fallacy", "displayName"=>"<b>fal·la·cy</b>", "dataset"=>{"dataset"=>"dictionary"}, "score"=>1}, "sectionType"=>"dictionary", "dictionary"=>{"word"=>"fallacy", "dictionaryType"=>"STANDARD", "definitionData"=>[{"word"=>"fallacy", "pos"=>"Noun", "meanings"=>[{"meaning"=>"a mistaken belief, especially one based on unsound argument.", "examples"=>["the notion that the camera never lies is a fallacy"], "synonyms"=>[{"nym"=>"misconception", "nymResult"=>{"query"=>"misconception", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"misbelief", "nymResult"=>{"query"=>"misbelief", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"delusion", "nymResult"=>{"query"=>"delusion", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"mistaken impression"}, {"nym"=>"error", "nymResult"=>{"query"=>"error", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"misapprehension", "nymResult"=>{"query"=>"misapprehension", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"misinterpretation"}, {"nym"=>"misconstruction", "nymResult"=>{"query"=>"misconstruction", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"mistake", "nymResult"=>{"query"=>"mistake", "dataset"=>{"dataset"=>"dictionary"}}}], "submeanings"=>[{"meaning"=>"a failure in reasoning that renders an argument invalid."}, {"meaning"=>"faulty reasoning; misleading or unsound argument.", "examples"=>["the potential for fallacy which lies behind the notion of self-esteem"]}]}], "phoneticText"=>"ˈfaləsē", "wordForms"=>[{"word"=>"fallacy", "form"=>"noun"}, {"word"=>"fallacies", "form"=>"plural noun"}]}]}}, "list_id"=>"1", "word"=>{"title"=>"fallacy", "full_data"=>{"dataType"=>"dictionary", "numToShow"=>1, "groupNumber"=>0, "groupResult"=>{"query"=>"fallacy", "displayName"=>"<b>fal·la·cy</b>", "dataset"=>{"dataset"=>"dictionary"}, "score"=>1}, "sectionType"=>"dictionary", "dictionary"=>{"word"=>"fallacy", "dictionaryType"=>"STANDARD", "definitionData"=>[{"word"=>"fallacy", "pos"=>"Noun", "meanings"=>[{"meaning"=>"a mistaken belief, especially one based on unsound argument.", "examples"=>["the notion that the camera never lies is a fallacy"], "synonyms"=>[{"nym"=>"misconception", "nymResult"=>{"query"=>"misconception", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"misbelief", "nymResult"=>{"query"=>"misbelief", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"delusion", "nymResult"=>{"query"=>"delusion", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"mistaken impression"}, {"nym"=>"error", "nymResult"=>{"query"=>"error", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"misapprehension", "nymResult"=>{"query"=>"misapprehension", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"misinterpretation"}, {"nym"=>"misconstruction", "nymResult"=>{"query"=>"misconstruction", "dataset"=>{"dataset"=>"dictionary"}}}, {"nym"=>"mistake", "nymResult"=>{"query"=>"mistake", "dataset"=>{"dataset"=>"dictionary"}}}], "submeanings"=>[{"meaning"=>"a failure in reasoning that renders an argument invalid."}, {"meaning"=>"faulty reasoning; misleading or unsound argument.", "examples"=>["the potential for fallacy which lies behind the notion of self-esteem"]}]}], "phoneticText"=>"ˈfaləsē", "wordForms"=>[{"word"=>"fallacy", "form"=>"noun"}, {"word"=>"fallacies", "form"=>"plural noun"}]}]}}, "date"=>"2015-05-08"}}
      List Load (0.1ms)  SELECT  "lists".* FROM "lists" WHERE "lists"."id" = $1 LIMIT 1  [["id", 1]]

    Unpermitted parameters: dataType, numToShow, groupNumber, groupResult, sectionType, dictionary

       (0.1ms)  BEGIN
      Word Exists (0.2ms)  SELECT  1 AS one FROM "words" WHERE ("words"."title" = 'fallacy' AND "words"."title" = 'fallacy') LIMIT 1
      SQL (0.2ms)  INSERT INTO "words" ("title", "date", "full_data", "list_id") VALUES ($1, $2, $3, $4) RETURNING "id"  [["title", "fallacy"], ["date", "2015-05-08 00:00:00.000000"], ["full_data", "{}"], ["list_id", 1]]
       (0.7ms)  COMMIT
    Completed 201 Created in 8ms (Views: 0.4ms | ActiveRecord: 1.4ms)

1 个答案:

答案 0 :(得分:1)

  

请注意,如果在指向哈希的键中使用permit,则不会允许所有哈希。您还需要指定哈希中的哪些属性应列入白名单。

     

http://edgeapi.rubyonrails.org/classes/ActionController/Parameters.html#method-i-permit

Rails并没有真正提供一种直接的方法来盲目地将嵌套参数哈希列入白名单。

你可以做一些像hackey这样的事情:

params.require(:word).permit(:full_data).tap do |whitelisted|
  whitelisted[:full_data] = params[:word][:full_data]
end