简体   繁体   中英

Rails Serializer not filtering data

I am trying to use Rail's Serializer on a JSON object being returned by an API in a Rails API app. I need to authenticate, ingest the API, filter the data, and rebroadcast the filtered data. No view is required.

To filter the data, I am trying to implement the Serializer - it's clear I haven't set it up correctly though. I can see it is working and in place because it is adding the initial object in front of the data it is returning (see data below: serialized object starts with kobo_data ). But it is returning all the fields of data, not just the fields I'm trying to call. In this case I'm trying to return just the field prikey , but it is returning all the fields of data.

I've tried to address issues in similar threads to this ( ActiveModel::Serializer in Rails - serializer methods ignored in JSON result , rails active model serializer not doing anything , Using ActiveModel::Serializer in Rails - JSON data differs between json and index response ), although since I don't have a .html view, I wonder if this might be related to the issue mentioned in the last link. But another tutorial I"ve done ( https://thesocietea.org/2015/03/building-a-json-api-with-rails-part-2-serialization/ ) employs serialization in a Rails-API app without a view, so I'm guessing it's not.

Any suggestions on what I'm doing wrong and how I can fix it?

Model:

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

Controller

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

Application Controller

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

kobo_api_serializer.rb

class KoboApiSerializer < ActiveModel::Serializer
  attributes :prikey
end

Gem file

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'

Data returned

{"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]

I just spoke with someone who walked me through the problem I was having, not all of which was related to the code I posted above. Am posting some details here. Am sure there are other ways to fix this, but this is how we covered it. Hope it's helpful.

Primary Issue: no each_serializer

Specifically related to the language as posted above: I was not including reference to each_serializer in my render statement in my model. This issue is referenced in this thread here as well: rails active model serializer not doing anything .

controller

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

If my database had been configured correctly, this should have fixed it for me.

Also, just in case there was an issue with the Active Model Serializers i was using, we updated my gem file to replace the line I had ( gem 'active_model_serializers', '~> 0.8.3' ) with the following:

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

Second Issue: incorrect db table name

However, I had an issue with the two-word table name I had created. I had created my table with a camelCase name structure, and rails was expecting separated_words (ie: with underscore).

You can see the table name here is koboApis :

original migration

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

You can see in my original schema that the table name is indeed kobo_apis , and not `koboApis'.

schema

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

The table Rails was expecting didn't even exist because of this.

We fixed this by running a second migration at the terminal: rails g migration RenameOldTableToNewTable . I then added this logic to the new migration file: rename_table :koboApis, :kobo_apis . Entire migration file here:

update migration file

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

I ran rake db:drop db:create db:migrate to update everything, and then my Rails Api page rendered correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM