Stack Level too deep ruby serializer without serializer on second level - ruby

I'm a newbie in ruby and I'm stuck on this strange error.
I'm getting stack level too deep when ever I hit this controller although only one of my object has a serializer.
I have got the following controller
def get_class
#class_sections = ClassSection.all
#class_sections = ClassSection.filter_by_class(#class_section.school_class.id).limit(nil)
if #class_sections.present?
render json: {
class_sections: ActiveModel::Serializer::CollectionSerializer.new(#class_sections, each_serializer: AdminClassSectionSerializer),
class: #class_section.class
}
else
render json: {message: "no Class Section found", status: 400}, status: 400
end
end
My Serializer:
class AdminClassSectionSerializer < ActiveModel::Serializer
attributes :id, :section, :faculty
belongs_to :faculty
belongs_to :section
end
class, faculty and section don't have a serializer but still it is giving me stack level too deep. Am I missing something here?

Related

Calling a Associated Controller Method Not Working

I have 3 models of User, Role and UserRole with their respective controllers as UsersController, RolesController and UserRolesController.
I have a method in the UserRoles controller which I would want to access through the Users controller but I keep having errors as explained below.
I have tried various means of even moving the method def self.add_roles_to_user(user, role) from the UsersRoles controller into the UserRole model and call it but I keep having the same error.
I have gone through lots of similar questions and various blogs, including those on this platform such as Calling a method from controller, and others but to no good results.
class UserRole < ApplicationRecord
# many-to-many association using join table with roles and user
belongs_to :user, inverse_of: :user_roles
belongs_to :role, optional: true, inverse_of: :user_roles
end
class User < ApplicationRecord
has_many :user_roles, inverse_of: :user
has_many :roles, through: :user_roles
end
class Role < ApplicationRecord
# table associations between role and user
has_many :user_roles, inverse_of: :role
has_many :users, through: :user_roles
end
class UserRolesController < ApplicationController
def self.add_roles_to_user(user, role)
if ! user.nil?
if role.length > 0
role.each do |sel_role|
#u_role = UserRole.new
#u_role.user_id = user_id
#u_role.role_id = sel_role.role_id
#u_role.save
end
end
end
end
end
class Users::RegistrationsController < Devise::RegistrationsController
def create_user
respond_to do |format|
if #user.save
# add roles
UserRoles.add_user_roles(params[:user], params[:role])
end
end
end
end
I am calling the add_uer_to_role method in the User controller when I am adding or creating a new user.
What I have noticed is that I keep getting different errors based on how I call the method.
For example, I expect to have no errors when I call the method like; UserRoles.add_roles_to_user(params[:user], params[:role]) but it gives the error NameError (uninitialized constant Users::RegistrationsController::UserRoles):
Hoping a good samaritan will come to my aid as soon as possible. Thanks in advance
If it is a common function, you can define it in application controller and call it. Else you can define in helper.
Please verify Calling a method from another controller
You can use that function as a module and use it:
# lib/common_stuff.rb
module CommonStuff
def common_thing
# code
end
end
# app/controllers/my_controller.rb
require 'common_stuff'
class MyController < ApplicationController
include CommonStuff
# has access to common_thing
end

Set a custom serializer in the include file with rails 5

I have this code that brings one vacancy from my model Vacancy and then render in json the attributes according to the serializer VacancyDetailSerializer:
Controller
vacancy = Vacancy.find(params[:id])
render json: vacancy, serializer: VacancyDetailSerializer,
include: [:restaurant]
The thing here is that in the include: [:restaurant] I want to specify a custom serializer the way I did with vacancy, because right now is taking the serializer of RestaurantSerializer, but I don't want to take that file, is there a way to do it with the include? Maybe is here in the controller, or maybe in the serializer?
If you have belongs_to :restaurant association in the VacancyDetailSerializer, then serializer for this association can be specified:
class VacancyDetailSerializer < ActiveModel::Serializer
belongs_to :restaurant, serializer: AnotherRestaurantSerializer
end
Or it can be overridden by providing a block:
class VacancyDetailSerializer < ActiveModel::Serializer
belongs_to :restaurant do
AnotherRestaurantSerializer.new(object.restaurant)
end
end
Or a custom association serializer lookup can be implemented.

how to call custom serializers in sinatra application

I am working on a backend of an application written in Sinatra.
It has a route "/notifications"
which renders all the notifications in JSON.
I want to change the json structure and wrote some custom serializer and it is failing now.
the error i get is
"{"message":"undefined method `read_attribute_for_serialization' for nil:NilClass"}"
I have a file called webservice/notification.rb
which selects a notification serializer.
the code is something like this
serializer = NotificationSerializer
json serialize(notifications, root: :notifications, each_serializer: serializer)
The NotificationSerializer is something like this.
class NotificationSerializer < Serializer
attributes :id, :tag, :event, :time, :read
has_one :reference, polymorphic: true, include: true
The reference here can be a lot of things.
the notification model defines reference as
def reference
company || contact || deal || invitation || meeting || todo || reference_email || reference_user ||
contact_import_job
end
now all of these models in reference have there Serializer implements in directory Serializer/*
I want to make custom Serializers for all of these which will render limited information.
how can I call my custom Serializer for things inside reference.
I wrote a custom serializer for notifications and called it like this inside my refernce function and it worked.
...|| UserNotificationSerializer.new(reference_user) || ...
but if i do the same for my other models i get the error given above.
what would be the correct way to call my custom serializers.
A good way to do it is to write an instance method on the model:
class Notification < ActiveRecord::Base
def public_attributes # or call it whatever
attributes_hash = attributes
# in activerecord, the attributes method turns a model instance into a hash
# do some modifications to the hash here
return attributes_hash
end
end
then say you're returning json in a controller:
get '/some_route' do
#notifications = Notification.all # or whatever
serialized_notifications = #notifications.map(&:public_attributes)
# For a single record, you could do #notification.public_attributes
json_data = serialized_notifications.to_json # a serialized array of hashes
content_type :json
return json_data
end

Validation not working on Class that extends ActiveModel::Naming, include ActiveModel::Validations

I and new to ruby and rails; I have the below ruby class definition that I am using in my rails 3 app. This class is simply used as a property container for contact information populated in my view on submit (form_for). I read a post where you can use ActiveModel directly apart from ActiveRecord, to perform validation, so I am trying it. I am getting the following exception when I check to see if the the object is valid? in my controller on postback. I assumed that valid? would be available being that I included ActiveModel::Validations; perhaps I am doing a few other things a$$ backwards. Any help would be appreciated:
undefined method `valid?' for #
Here's my class definition, further down is how I am handling it in my controller action:
require 'active_model'
class ContactModel
extend ActiveModel::Naming
include ActiveModel::AttributeMethods
include ActiveModel::Validations
include ActiveModel::Conversion
validates_presence_of :first_name, :last_name, :email_address, :email_address_confirmed, :subject, :contact_message
attr_accessor :first_name, :last_name, :email_address, :email_address_confirmed,
:telephone_number, :subject, :contact_message
Just messing around testing.
validates_each :first_name, :last_name do |record, attr, value|
record.errors.add attr, 'starts with z.' if value.to_s[0] == z
end
...
end
In my controller/action...
def send_email
##contact_model = ContactModel.new().initialize_copy(params[:contact_model])
#contact_model = params[:contact_model].dup
respond_to do |format|
if (#contact_model.valid?)
# Tell the UserMailer to send a welcome Email after save
ContactMailer.contact_email(#contact_model).deliver
format.html { redirect_to(#contact_model, notice: 'Email successfully sent.') }
format.json { render json: #contact_model, status: :created, location: #contact_model }
else
# What to do here?
end
end
end
In your controller you are setting #contact_model to a hash, params[:contact_model], and then calling valid? on it. You need create an instance of ContactModel and call valid on that. Like so:
#contact_model = ContactModel.new(params[:contact_model])
if (#contact_model.valid?)
...
I see commented out code that calls ContactModel.new(), but that's not how you want to do it anyway. Also, there is no reason to dup() or initialize_copy() on the params stuff.

ActiveRecord::UnknownAttributeError when using STI models in Rails

I made the following models:
class Request < ActiveRecord::Base
end
class UrgentRequest < Request
has_one:note
end
class Note < ActiveRecord::Base
attr_accessible :request_id,....
belongs_to :urgent_request, :foreign_key=>'request_id', :class_name=>'Request'
end
In my controller I've set up an action to create an UrgentRequest object:
def new_scheduled_request
#request = UrgentRequest.new
#request.build_note #<-- getting error here
respond_to do |format|
format.html # new.html.erb
format.json { render json: #request }
end
end
I'm getting the following error:
ActiveRecord::UnknownAttributeError in RequestsController#new_urgent_request
unknown attribute: urgent_request_id
The line number is where I'm invoking the build_note call. The form on the page is supposed to be a nested form. What's going on here and how can I fix it?
Uh never mind I found out the issue. Apparently I had to explicitly mention in the UrgentRequests model in the has_one:note association the foreign key and class name parameters. Works fine now!

Resources