I'm using Active Model Serializer 0.10.7 in rails 5
and I wanna know how to access devise current_user in serializer.
current_user is supposed to be set for scope by default.
according to doc
https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/general/serializers.md#controller-authorization-context
but my code doesn't work well...
anybody knows about this?
class BookSerializer < ActiveModel::Serializer
attributes :id, :title, :url, :image, :is_reviewed
def is_reviewed
object.reviews.pluck(:user_id).include?(current_user.id)
end
end
and Book controller look like this.
class BooksController < ApplicationController
def index
#books = Book.order(created_at: :desc).page(params[:page])
respond_to do |format|
format.html
format.json {render json: #books, each_serializer: BookSerializer}
end
end
end
It is possible to pass a scope into your serializer when instantiating it in the controller (or elsewhere for that matter). I appreciate that this is for individual objects and not arrays of objects:
BookSerializer.new(book, scope: current_user)
Then in your Book Serializer you can do:
class BookSerializer < ActiveModel::Serializer
attributes :id, :title, :url, :image, :is_reviewed
private
def is_reviewed
object.reviews.pluck(:user_id).include?(current_user.id)
end
def current_user
scope
end
end
Devise doesn't expose the current_user helper to models or serializers - you can pass the value to the model from the controller, or set it in a storage somewhere.
Some examples from other answers:
https://stackoverflow.com/a/3742981/385532
https://stackoverflow.com/a/5545264/385532
in application controller:
class ApplicationController < ActionController::Base
...
serialization_scope :view_context
end
in serializer:
class BookSerializer < ActiveModel::Serializer
attributes :id, :title, :url, :image, :is_reviewed
def is_reviewed
user = scope.current_user
...
end
end
If you are using active_model_serializers gem, then it is straight forward.
In your serializer just use the keyword scope.
Eg:-
class EventSerializer < ApplicationSerializer
attributes(
:id,
:last_date,
:total_participant,
:participated
)
def participated
object.participants.pluck(:user_id).include?(scope.id)
end
end
You can also pass view context into serializer from controller when you want to intialize serializer your self instead of render json: book.
# controller
BookSerializer.new(book, scope: view_context)
# serializer
class BookSerializer < ActiveModel::Serializer
attributes :id, :title, :url, :image, :is_reviewed
private
def is_reviewed
object.reviews.pluck(:user_id).include?(scope.current_user.id)
end
end
seems there is a typo, you have is_reviewed and you defined method has_reviewed
so it should be like this
class BookSerializer < ActiveModel::Serializer
attributes :id, :title, :url, :image, :is_reviewed
def is_reviewed
object.reviews.pluck(:user_id).include?(current_user.id)
end
end
I'm using Rails 5, gem 'active_model_serializers' and I have this situation:
controllers/leagues_controller.rb:
class LeaguesController < ApplicationController
before_action :authenticate_user
before_action :set_league, only: [:show, :update, :destroy]
# GET /leagues
def index
#leagues = League.all
render json: #leagues
end
# GET /leagues/1
def show
render json: #league, include: ['teams'] # Here I need some way to order
end
private
# Use callbacks to share common setup or constraints between actions.
def set_league
#league = League.find(params[:id])
end
models/league.rb:
class League < ApplicationRecord
has_many :teams
end
serializers/league_serializer.rb:
class LeagueSerializer < ActiveModel::Serializer
attributes :id, :name, :address, :teams_num
has_many :teams
has_many :menus, serializer: ProductSerializer
end
I need to order teams by "goals" or other attribute in the team model. How to do that? And where? I can't do this below?
def show
render json: #league, include: ['teams'], :order => 'goals DESC'
end
What is the logic? I have to order in my serializer? In my model?
Why I can't use something like this? It gives to me "undefined method includes". Why?
def show
#league = #league.includes(:team).order(goals: :desc)
render json: #league
end
How do I add parameters to methods for rendering the current place in favorites?
I tried this:
class Place < ActiveRecord::Base
has_and_belongs_to_many :users
def in_fav(user)
if user.places.include?Place.find(id)
return true
else
return false
end
end
end
class User < ActiveRecord::Base
has_and_belongs_to_many :places
end
class PlacesController < ApplicationController
places = Place.all
user = User.first
render json: {desc:true, status:1; data: places}.to_json(:methods => :in_fav(user))
end
I find same problem here
attr_accessor :current_user
def is_favorited_by_user?(user=nil)
user ||= current_user
end
#drops.current_user = current_user
render :json => #drops.to_json(:methods => :is_favorited_by_user?)
I don't understand current_user - it's assocciations? and how to use method current_user for collection #drops
I'm using active-model-serializers for my API.
I have a model (Task) that has many subtasks(always Task model), called children.
I do this recursive has_many association thanks to ancestry gem (https://github.com/stefankroes/ancestry)
It works all enough well, but I have this problem:
Task has an association with User, but while active-model-serializers, export user for the main object, it doesn't show user details for also all children.
This is my serializer:
class TaskSerializer < ActiveModel::Serializer
attributes :id, :name, :details, :user_id
belongs_to :user
has_many :children
end
This is my controller:
class Api::V1::TasksController < Api::V1::BaseController
respond_to :json
def index
#tasks = current_user.company.tasks
respond_with #tasks, location: nil
end
end
And this is my model:
class Task < ActiveRecord::Base
has_ancestry
belongs_to :user
end
I've also tried to do this in my model:
class Api::V1::TasksController < Api::V1::BaseController
respond_to :json
def index
#tasks = current_user.company.tasks
render json: #tasks,
each_serializer: TaskSerializer,
status: :ok
end
end
But doesn't work...I've the user details for the parent object, but not for the children(where he only show me user_id, without all User object)
Any suggestions ?
Have you tried adding a serializer for the Children model or querying them as a explicit attribute like so?
class TaskSerializer < ActiveModel::Serializer
attributes :id, :name, :details, :user_id, :children
def children
object.children
end
end
When I'm going to index action it outputs whole data from my model, as I understood when I'm going to show action it supposed to output only object depends on id param, but in my case it output the same data as it were in index action.
My active model serializer:
class CategorySerializer < ApplicationSerializer
attributes :id, :name, :alias, :parent_category_id, :position, :menu, :status
has_many :subcategories
has_many :products
end
Controller:
module API
module Store
class CategoriesController < ApplicationController
def index
#categories = Category.all
if params[:name]
#categories = Category.find_by(name: params[:name])
end
puts #categories
render json: #categories
end
def show
#category = Category.find(params[:id])
render json: #category
end
end
end
end