Josh M.
Josh M.

Reputation: 435

Rails serializer default value

I have a simple blog application where users can vote on articles. When a user is logged in the index method in my articles controller returns an additional column indicating whether the current_user has voted for the article. I do this with a raw SQL join.

#app/controllers/articles_controller.rb
@articles = Article.joins("LEFT OUTER JOIN 
                        (SELECT * FROM article_votes 
                        WHERE article_votes.user_id = #{uid.id}) AS av
                        ON articles.id = av.article_id")
      .select("articles.*,CASE WHEN av.user_id IS NULL THEN 0 ELSE 1 END AS user_voted")
      .where(safe_params)
      .order(order)

render json: @articles

Sometimes I want to return articles from the index method when a user is not logged in by simply calling the following. There is no user_voted count for this data, so a default of 0 would be appropriate.

#app/controllers/articles_controller.rb
@articles = Article.all
render json: @articles

However when I try this I get the following error.

NoMethodError (undefined method `user_voted' for #<Article:0x007fa584b95808>):
  app/controllers/articles_controller.rb:80:in `index'

I get a similar error when I explicitly add a user_voted method to the serializer.

#app/serializers/article_serializer.rb
class ArticleSerializer < ActiveModel::Serializer
  attributes :id, :title, :subheading, :body, :user_voted
  has_one :user

  def user_voted
    object.user_voted ||= 0
  end
end


NoMethodError (undefined method `user_voted' for #<Article:0x0000000490aa98>):
  app/serializers/article_serializer.rb:13:in `user_voted'
  app/controllers/articles_controller.rb:80:in `index'

Upvotes: 0

Views: 1494

Answers (1)

Inpego
Inpego

Reputation: 2667

Add to Article model:

def user_voted
  self['user_voted'] || 0
end

And then you can remove user_voted from serializer.

Upvotes: 2

Related Questions