我正在尝试在Rails API应用程序中由API返回的JSON对象上使用Rail的Serializer。我需要验证,摄取API,过滤数据,并重新广播过滤后的数据。无需查看。
为了过滤数据,我正在尝试实现Serializer - 很明显我还没有正确设置它。我可以看到它正在工作并且到位,因为它在它返回的数据前面添加了初始对象(参见下面的数据:序列化对象以kobo_data
开头)。但它正在返回所有数据领域,而不仅仅是我试图调用的字段。在这种情况下,我尝试仅返回字段prikey
,但它返回所有数据字段。
我已经尝试解决类似线程中的问题(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),但因为我没有.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]
答案 0 :(得分:5)
我刚跟一个跟我解决过我遇到的问题的人谈过,并不是所有与我上面发布的代码有关。我在这里发布一些细节。我确定还有其他方法可以解决这个问题,但这就是我们如何解决这个问题。希望它有用。
each_serializer
与上面发布的语言特别相关:我在模型中的each_serializer
语句中未提及render
的引用。此问题在此处引用了此问题: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', '~> 0.8.3'
):
gem 'active_model_serializers', :git => 'git://github.com/AskNative/active_model_serializers.git', :branch => '0-8-stable'
但是,我创建的双字表名有问题。我用camelCase名称结构创建了我的表,rails期望使用separate_words(即:使用下划线)。
您可以在此处看到表格名称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页面正确呈现。