0

Below are my model definitions

# GoogleApp model
class GoogleApp < ApplicationRecord
  has_many :gmail_users, foreign_key: 'app_account', primary_key: 'google_account', dependent: :destroy
  has_many :gmail_threads, foreign_key: 'app_account', primary_key: 'google_account', dependent: :destroy
end

# GmailUser model
class GmailUser < ApplicationRecord
  belongs_to :google_app, foreign_key: 'app_account', primary_key: 'google_account', optional: true
  has_one :gmail_thread, foreign_key: 'user_id', primary_key: 'user_id', dependent: :destroy
end

# GmailThread model
class GmailThread < ApplicationRecord
  belongs_to :google_app, foreign_key: 'app_account', primary_key: 'google_account', optional: true
  belongs_to :gmail_user, foreign_key: 'user_id', primary_key: 'user_id', optional: true
  has_many :gmail_messages, -> { order "sent_at asc" }, foreign_key: 'thread_id', primary_key: 'thread_id', dependent: :destroy
end

# GmailMessage model
class GmailMessage < ApplicationRecord
  belongs_to :gmail_thread, foreign_key: 'thread_id', primary_key: 'thread_id', optional: true
  has_many :gmail_attachments, foreign_key: 'message_id', primary_key: 'message_id', dependent: :destroy
end

# GmailAttachment model
require "base64"
class GmailAttachment < ApplicationRecord
  belongs_to :gmail_message, foreign_key: 'message_id', primary_key: 'message_id', optional: true

  def encode_as_base64_data
    Base64.encode64(self.base64_data)
  end
end

I'm trying to return an instance of GoogleApp with the following nested associations

render status: 200, json: @google_app.to_json({include: [gmail_users: {include: [gmail_thread: {include: [gmail_messages: {include: {gmail_attachments: (except: :base64_data, methods: [:encode_as_base64_data])}}]}]}]})

But this gives a syntax error on except i.e

SyntaxError (/home/work/projects/backend/app/controllers/gmail_controller.rb:40: syntax error, unexpected tLABEL ...e: {gmail_attachments: (except: :base64_data, methods: [:enc... ... ^~~~~~~ ):

I haven't been able to solve this syntax error issue. When I do it like this

render status: 200, json: GmailAttachment.first.to_json(except: [:base64_data], methods: [:encode_as_base64_data])

Then it works as expected.

Masroor
  • 1,484
  • 3
  • 14
  • 23

1 Answers1

1

exclude should wrap in {} instead of ()

render status: 200, json: @google_app.to_json({include: [gmail_users: {include: [gmail_thread: {include: [gmail_messages: {include: {gmail_attachments: {except: :base64_data, methods: [:encode_as_base64_data]}}]}]}]})

I would suggest to use jbuilder Gem to include nested models in a maintainable way.

Sampat Badhe
  • 8,710
  • 7
  • 33
  • 49
  • thanks. I noticed that if I define a method in a rails model with the same name as the attribute name that also performs the same function as we're doing here using the except :[some_attribute], methods: [:some_method]. i.e we hijack the attribute by using a same named function in the model. see https://stackoverflow.com/questions/21835116/how-can-i-overwrite-a-getter-method-in-an-activerecord-model – Masroor Oct 18 '20 at 16:16