【问题标题】:Rails Serializer not filtering dataRails 序列化器不过滤数据
【发布时间】:2016-10-20 13:15:51
【问题描述】:

我正在尝试在 Rails API 应用程序中的 API 返回的 JSON 对象上使用 Rail 的序列化程序。我需要进行身份验证、摄取 API、过滤数据并重新广播过滤后的数据。无需查看。

为了过滤数据,我正在尝试实现序列化程序 - 很明显我没有正确设置它。我可以看到它正在工作并且就位,因为它在它返回的数据前面添加了初始对象(请参阅下面的数据:序列化对象以kobo_data 开头)。但它正在返回所有数据字段,而不仅仅是我试图调用的字段。在这种情况下,我试图只返回字段prikey,但它正在返回所有数据字段。

我尝试在与此类似的线程(ActiveModel::Serializer in Rails - serializer methods ignored in JSON resultrails active model serializer not doing anythingUsing ActiveModel::Serializer in Rails - JSON data differs between json and index response)中解决问题,但由于我没有 .html 视图,我想知道这是否与上一个链接中提到的问题。但是我完成的另一个教程 (https://thesocietea.org/2015/03/building-a-json-api-with-rails-part-2-serialization/) 在没有视图的 Rails-API 应用程序中使用了序列化,所以我猜它不是。

关于我做错了什么以及如何解决它有什么建议吗?

型号:

class KoboApi < ActiveRecord::Base    
    require 'rest_client'
    USERNAME = ENV['KOBO_API_USER']
    PASSWORD = ENV['KOBO_API_PWD']
    SURVEY = ENV['KOBO_API_SURVEY']
    # API_BASE_URL = "https://kc.kobotoolbox.org/api/v1/"
    API_BASE_URL = "https://sg.smap.com.au/api/v1"
    def self.get_api_info
        uri = "#{API_BASE_URL}/data/#{SURVEY}?format=json"
        rest_resource = RestClient::Resource.new(uri, USERNAME, PASSWORD)
        response = rest_resource.get
        JSON.parse response
    end
end

控制器

class KoboDataController < ApplicationController
    def index
        @kobo_info = KoboApi.get_api_info
        render json: @kobo_info
    end
end

应用控制器

class ApplicationController < ActionController::API
    include ActionController::Serialization
end

kobo_api_serializer.rb

class KoboApiSerializer < ActiveModel::Serializer
  attributes :prikey
end

宝石文件

source 'https://rubygems.org'

gem 'active_model_serializers', '~> 0.8.3'
gem 'rest-client'
gem 'pg'
gem 'rails', '4.2.5.1'
gem 'rails-api'
gem 'spring', :group => :development

# gem for environment variables
gem 'dotenv-rails', :groups => [:development, :test]
gem 'figaro'

数据返回

{"kobo_data":[{"prikey":"1","Upload Time":"2016-06-17 11:11:38.802+00","Version":"1","Complete":"t","Survey Notes":"","Location Trigger":"","deviceid":"webworm"....[data truncated]

【问题讨论】:

  • 渲染 json:ActiveModelSerializers::KoboApiSerializer.new(kobo_info, {})
  • 谢谢 - 用你的建议替换我的渲染 json 行会给我一个 uninitialized constant KoboDataController::ActiveModelSerializers 错误。
  • 是否包含活动模型序列化程序 gem?尝试只渲染 json:KoboApiSerializer.new(kobo_info, {})
  • 我遇到了与我的数据库和数据相关的其他问题,这些问题即使在尝试此操作后也使我的应用程序无法工作 - 在我发布的答案中详细描述了我的数据库问题。如果我的数据库表名没有问题,我想这会解决它。稍后将尝试确认。再次感谢!

标签: ruby-on-rails json active-model-serializers


【解决方案1】:

我刚刚与一位指导我解决了我遇到的问题的人交谈,并非所有问题都与我上面发布的代码有关。我在这里发布一些细节。我确信还有其他方法可以解决这个问题,但这就是我们介绍它的方式。希望它有帮助。

主要问题:否 each_serializer

与上面发布的语言特别相关:我的模型中的render 语句中没有包含对each_serializer 的引用。此处的此线程中也引用了此问题:rails active model serializer not doing anything

控制器

class KoboDataController < ApplicationController
  def index
    @kobo_info = KoboApi.get_api_info
    @kobo_info.each do |kobo_info|
      begin
        #this pulls in new records that have been added to the api and adds them to the database.  it doesn't pull in records from the api that are already in the db
        KoboApi.find_or_create_by(lemurs_quantity: kobo_info['lemurs_quantity'], month_and_year:  Date.parse(kobo_info['month_and_year']))
          # some of my records don't have valid date values, so `rescue` is added to keep rails from returning a `notfound` page.
          # quick tutorial here:  http://www.rubytutorial.io/rails-rescue_from/
      rescue
        puts "rescued"
      end
    end
    # I needed to update my render logic.
    # see addition of `each_serializer` here.
    # @kobo_info has also changed to KoboApi.all as well.
    render(
      json: KoboApi.all,
      each_serializer: KoboApiSerializer
    )
  end
end

如果我的数据库配置正确,这应该已经为我修复了。

此外,为了以防我使用的 Active Model Serializers 出现问题,我们更新了我的 gem 文件以将我的行 (gem 'active_model_serializers', '~&gt; 0.8.3') 替换为以下内容:

gem 'active_model_serializers', :git => 'git://github.com/AskNative/active_model_serializers.git', :branch => '0-8-stable'  

第二个问题:数据库表名不正确

但是,我创建的双字表名存在问题。我用驼峰命名结构创建了我的表,并且 rails 期望使用分词(即:带下划线)。

可以看到这里的表名是koboApis:

原始迁移

class KoboApis < ActiveRecord::Migration
  def change
    create_table :koboApis do |t|
      t.integer :lemurs_quantity
      t.date  :month_and_year
      t.text :_geolocation
      t.text :lemur_category
    end
  end
end

您可以在我的原始模式中看到表名确实是kobo_apis,而不是“koboApis”。

架构

ActiveRecord::Schema.define(version: 20160620063545) do

  create_table "kobo_apis", force: :cascade do |t|
    t.integer "lemurs_quantity"
    t.date    "month_and_year"
    t.text    "_geolocation"
    t.text    "lemur_category"
  end
end

因此,Rails 所期望的表甚至不存在。

我们通过在终端运行第二次迁移来解决此问题:rails g migration RenameOldTableToNewTable。然后我将此逻辑添加到新的迁移文件中:rename_table :koboApis, :kobo_apis。整个迁移文件在这里:

更新迁移文件

class RenameOldTableToNewTable < ActiveRecord::Migration
  def change
     rename_table :koboApis, :kobo_apis
  end
end

我运行rake db:drop db:create db:migrate 来更新所有内容,然后我的 Rails Api 页面正确呈现。

【讨论】:

  • 一段时间后重温这个(我有更多的经验),我看到我在这里的班级名字很糟糕。我确实重做了这个项目并重命名了类Response,引用变量@responses 的控制器ResponsesController,并调用了我的序列化程序ResponseSerializer。表名是responses。我确信我仍然可以做出一些改进,但这样会更清晰。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多