ActiveModel Serializers: How do I serialize a resource collection?
Solution 1
turns out I need to include v0.9 of the gem
gem 'active_model_serializers', github: 'rails-api/active_model_serializers', branch: '0-9-stable'
Solution 2
you could try change:
def index
user = User.find_by(username: params[:username])
bookmarks = user.bookmarks
bookmarks.map { |bookmark| ::BookmarkSerializer.new(bookmark)}.to_json #updated line
end
to:
def index
user = User.find_by(username: params[:username])
bookmarks = user.bookmarks
render json: bookmarks.map { |bookmark| ::BookmarkSerializer.new(bookmark)}
end
Amit Erandole
I am the content head of my very own web marketing agency, based out of Mumbai. I am a writer by profession but the dark side of my nature seems to have turned towards programming. I will have my vengeance!! I love learning javascript and ruby and amazed by the power of meta programming and shit I don't know but am very curious about.
Updated on June 09, 2022Comments
-
Amit Erandole almost 2 years
I have a
bookmarks
resource and have mapped it to servejson
by default under myapi
namespace like so in myroutes.rb
:namespace :api, defaults: {format: 'json'} do resources :bookmarks get ':username', to: 'users#index' get ':username/bookmarks/:id', to: 'users#show' end
I have a
Api::UsersController
controller and a supportingBookmarkSerializer
that works just fine on an individual bookmark resource likehttp://localhost:3000/api/emma_carter/bookmarks/87
But when I try to hit
http://localhost:3000/api/emma_carter
which is supposed to serve all bookmarks owned by the user, I get all different kinds of errors. Here is myApi::UsersController
module Api class UsersController < ApplicationController respond_to :json def index user = User.find_by(username: params[:username]) bookmarks = user.bookmarks render json: bookmarks end def show user = User.find_by(username: params[:username]) bookmark = user.bookmarks.find_by(params[:id]) render json: bookmark end end end
The
show
method works but the index method gives meArgumentError in Api::UsersController#index
wrong number of arguments (1 for 0)
UPDATE: Full stack trace here: https://gist.github.com/amite/b79fc42bfd73de5a07bd
screenshot
Here is the serializer:
class BookmarkSerializer < ActiveModel::Serializer attributes :id, :url, :title, :domain, :notes, :image, :created, :username belongs_to :user def created object.created_at end def username user.username end end
Looking at other solutions on stack overflow, I have also tried other versions of my
index
method:def index user = User.find_by(username: params[:username]) bookmarks = user.bookmarks bookmarks.map { |bookmark| ::BookmarkSerializer.new(bookmark)}.to_json #updated line end
This gives me the error:
Missing template api/users/index, application/index with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}.
Next the last version of my
index
method looks like this:def index user = User.find_by(username: params[:username]) bookmarks = user.bookmarks ActiveModel::ArraySerializer.new(bookmarks, each_serializer: ::BookmarkSerializer).to_json end
This gives me the error
uninitialized constant ActiveModel::ArraySerializer
What am I doing wrong? I am using
rails 4.1.5
and the github version of theactive_model_serializers
gem.gem 'active_model_serializers', github: 'rails-api/active_model_serializers'
UPDATE: Since I am trying to output a collection of
bookmarks
I also tried using a separate serializerBookmarksSerializer
but I am getting the same error:ArgumentError in Api::UsersController#index wrong number of arguments (1 for 0)
UPDATE2: Here is a version of the
index
method that kinda works in the sense that it renders the resource collection injson
format:def index user = User.find_by(username: params[:username]) bookmarks = user.bookmarks respond_with bookmarks.to_json end
But this still does not use the
BookmarksSerializer
class BookmarksSerializer < ActiveModel::Serializer attributes :id, :title end
It just outputs the default hash
Full Gemfile
source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '4.1.5' # Use mysql as the database for Active Record gem 'mysql2' # Use SCSS for stylesheets gem 'sass-rails', '~> 4.0.3' # Use Uglifier as compressor for JavaScript assets gem 'uglifier', '>= 1.3.0' # Use CoffeeScript for .js.coffee assets and views gem 'coffee-rails', '~> 4.0.0' # See https://github.com/sstephenson/execjs#readme for more supported runtimes # gem 'therubyracer', platforms: :ruby gem 'bourbon' gem 'neat' gem 'bitters' gem 'refills' gem 'wisper' gem 'rails-ioc' gem 'reform' gem 'cells' gem "pundit" gem 'active_model_serializers', github: 'rails-api/active_model_serializers' gem "font-awesome-rails" gem 'simple_form' # Use jquery as the JavaScript library gem 'jquery-rails' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 2.0' # bundle exec rake doc:rails generates the API under doc/api. gem 'sdoc', '~> 0.4.0', group: :doc group :development, :test do # Call 'debugger' anywhere in the code to stop execution and get a debugger console gem 'byebug' gem 'ffaker' gem 'pry-rails' gem 'capybara' gem 'factory_girl_rails' gem 'database_cleaner' gem 'capybara-webkit' gem 'rspec-cells' # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring gem 'spring' gem 'spring-commands-rspec' gem 'rspec-rails' gem 'guard-rspec' gem 'rb-fsevent' if `uname` =~ /Darwin/ end # Use ActiveModel has_secure_password gem 'bcrypt', '~> 3.1.7' # Use unicorn as the app server # gem 'unicorn' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development # Use debugger # gem 'debugger', group: [:development, :test]
-
Amit Erandole over 9 yearstried that - it returns the default json hash map - the serializer simply does not have any affect
-
Igor Guzak over 9 yearseven with
}.to_json
in the end -
Amit Erandole over 9 yearsyup I tried with that too - wasted entirety of last night with this - see simplified version of the same question: stackoverflow.com/questions/25578786/…
-
Igor Guzak over 9 yearsjust for check, could you try leave just few attributes in
BookmarkSerializer
(id, title) and thenrender json: bookmarks
?