ruby-on-rails - Rails 4 不允许的参数 - JSON 数据

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

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

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

当我尝试插入 JSON 数据时收到“不允许的参数”错误。我研究过,这似乎是由于 Rails 4 nested params

我尝试将嵌套括号添加到 Words Controller 中的 word_params 方法中,但随后得到“不允许的参数:dataType、numToShow、groupNumber、groupResult、sectionType、dictionary”...这是 API 响应的一部分。

是否有一种更简单的方法来允许完整的 JSON 数据,而无需在 Controller 的 word_params 方法中遍历并专门定义每个嵌套参数?

方案.rb

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

文字 Controller

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)

最佳答案

Note that if you use permit in a key that points to a hash, it won't allow all the hash. You also need to specify which attributes inside the hash should be whitelisted.

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

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

你可以做一些像黑客一样的事情:

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

关于ruby-on-rails - Rails 4 不允许的参数 - JSON 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30134509/

相关文章:

ruby-on-rails - 即使使用 :step,Rails number_field_tag 也不会接受 float

ruby-on-rails - rails 布线格式

ruby-on-rails - Rails 3 未初始化常量 ActiveRecord::RecordInvalid

android - Espresso 测试时如何从 Asset 文件夹中读取 json 文件?

ios - JSONModel - 使用同一 JSONModel 中的其他属性分配 JSONModel 属性的值

javascript - Rails 表单输入字段充满了 Bootstrap 3 模式对话框

ruby-on-rails - 自定义 ActionMailer 预览标题

sql - 如何在SQL中使用group by生成json数据

ruby-on-rails - Ruby on Rails 扩展大型 Rails 项目的配置约定 (CoC) 问题

javascript - 我可以在 Rails 表单上下载带有 `remote: true` 的 CSV 文件吗?