Stack Level Too Deep Error in Ruby on Rails

Stack level too deep error in Ruby on Rails

I've found the solution to this issue...

I'm using Rails 3 and my class looks like this (and the problematic methods was this too)

class Organization < ActiveRecord::Base
def self.parents
@organizations = self.find :all, :conditions => ['is_company = ? ',true]
select_choice = I18n.t("select") + " "+ I18n.t("segments.description")
@organization_parents = [select_choice]
for organization in @organizations
@organization_parents << [organization.name, organization.id]
end
return @organization_parents
end
#...
end

I did have to hack a lot in the code to find out something was wrong with the named_scope on the line

@organizations = self.find :all, :conditions => ['is_company = ? ',true]

So I had to change it to something like this

@organizations = Organization.where("is_company = ?",true)

But it was wrong too.. So I decided to add an scope for this below the class name so the final code looks like this:

class Organization < ActiveRecord::Base
scope :company, where("is_company = ?",true)

def self.parents
@organizations = self.company
select_choice = I18n.t("select") + " "+ I18n.t("segments.description")
@organization_parents = [select_choice]
for organization in @organizations
@organization_parents << [organization.name, organization.id]
end
return @organization_parents
end
#...
end

So using this line with the scope

@organizations = self.company

it worked flawlessly in every part of the code.

I was wondering if the named_scope is deprecated when using class methods or they are not supported from now and throws an error and not a warning before

Thanks for your help
Leo

How to fix the SystemStackError (stack level too deep) in rails model

In your code there is a before_create callback that calls the remember method. In this remember method you call update_attribute which internally tries to save the record which calls the same before_create callback.

To fix this just use a method to sets the remember_digest attribute without triggering save.

For example:

def remember 
self.token = User.new_token
self.remember_digest = User.create_digest(token)
end

ruby on rails. stack level too deep error

The stack level too deep error usually happens because your code is stuck in a loop: either a method calling itself, or two methods calling each other repeatedly.

In your case i think it's caused by the validate_order method. You are calling this in a before_save callback, and the method calls self.save, which will trigger the callback, which will call the method again, which will save again, which will trigger the callback etc etc.

Think about this for a moment - it doesn't make sense to save an object as part of it's "before_save" functionality does it?

What i suspect you want to do is to just validate the object, and if validation fails that will automatically block the save anyway. Something like this

validate :validate_order

def validate_order
@deposit = self.deposit
@income = @deposit.income
@cashout = self.order_sum
if @income - @cashout <= 0
self.errors.add(:deposit, "is too small")
end
end

This is just an example as i don't know what the actual logic of what you are testing is supposed to be.

Ruby on Rails - SystemStackError (stack level too deep) when doing after_update

It's because you have again call the update method in your private method. That means the application will go in infinite loop and into dead conditions.

You just need to set the attribute into the self no need to call the update method inside the private method.

class Post < ActiveRecord::Base

before_update :navid_tadding_atgs

private

def navid_tadding_atgs
self.added_by_me = 'yes'
end

SystemStackError (stack level too deep) when deleting a record

The stack level too deep error occurs when you try to delete a record with relationships that declare dependent: :destroy linking back to each other.

Example:

class Order < ActiveRecord::Base
has_many :items, dependent: :destroy
end

class Item < ActiveRecord::Base
belongs_to :order, dependent: :destroy
end

Removing dependent: :destroy from the Item assocation should resolve the circular error/stack level too deep.

Arel: I get stack level too deep error when I try to get SQL from Arel

Now that I understand the desired output here is how I would go about this

class Report

JOB_STATS = Arel::Table.new('jobstat_jobs')
CORE_MEMBERS = Arel::Table.new('core_members')
SESSIONS = Arel::Table.new('sessions_projects_in_sessions')

def additions
# This could be ported too if I knew the tables for end_time, start_time, and num_nodes
{
node_hours: Arel.sql("((extract(epoch from (end_time - start_time))/ 3600))*num_nodes").sum,
jobs: JOB_STATS[:id].count
}
end

def n
@n ||= _base_query.as('n')
end

def s
@s ||= _base_query
.project(JOB_STATS[:state])
.group(JOB_STATS[:state]).as('s')
end

def alias_columns
additions.keys.flat_map do |key|
[s[key].as("s_#{key}"),
n[key].as("n_#{key}"),
(s[key] / n[key]).as("share_#{key}")]
end
end

def query
Arel::SelectManager.new.project(
s[:project_id].as('id'),
s[:state],
*alias_columns
)
.from(s)
.join(n).on(s[:project_id].eq(n[:project_id]))
end

def to_sql
query.to_sql
end

private
def cast_as_decimal(value,alias_name:)
Arel::Nodes::NamedFunction.new(
"CAST",
[Arel::Nodes::As.new(value, Arel.sql('DECIMAL'))]
).as(alias_name.to_s)
end
def _base_query
JOB_STATS
.project(
CORE_MEMBERS[:project_id],
*additions.map {|k,v| cast_as_decimal(v, alias_name: k)})
.join(CORE_MEMBERS).on(CORE_MEMBERS[:login].eq(JOB_STATS[:login]))
.outer_join(SESSIONS).on(SESSIONS[:project_id].eq(CORE_MEMBERS[:project_id]))
.where(JOB_STATS[:state].not_in(['COMPLETETED', 'RUNNING', 'unknown']))
.group(CORE_MEMBERS[:project_id])
end
end

Result of Report.new.to_sql

SELECT 
s."project_id" AS id,
s."state",
s."node_hours" AS s_node_hours,
n."node_hours" AS n_node_hours,
s."node_hours" / n."node_hours" AS share_node_hours,
s."jobs" AS s_jobs,
n."jobs" AS n_jobs,
s."jobs" / n."jobs" AS share_jobs
FROM
(
SELECT
"core_members"."project_id",
CAST(SUM(((extract(epoch from (end_time - start_time))/ 3600))*num_nodes) AS DECIMAL) AS node_hours,
CAST(COUNT("jobstat_jobs"."id") AS DECIMAL) AS jobs,
"jobstat_jobs"."state"
FROM
"jobstat_jobs"
INNER JOIN "core_members" ON "core_members"."login" = "jobstat_jobs"."login"
LEFT OUTER JOIN "sessions_projects_in_sessions" ON "sessions_projects_in_sessions"."project_id" = "core_members"."project_id"
WHERE
"jobstat_jobs"."state" NOT IN (N'COMPLETETED', N'RUNNING', N'unknown')
GROUP BY
"core_members"."project_id",
"jobstat_jobs"."state"
) s
INNER JOIN (
SELECT
"core_members"."project_id",
CAST(SUM(((extract(epoch from (end_time - start_time))/ 3600))*num_nodes) AS DECIMAL) AS node_hours,
CAST(COUNT("jobstat_jobs"."id") AS DECIMAL) AS jobs
FROM
"jobstat_jobs"
INNER JOIN "core_members" ON "core_members"."login" = "jobstat_jobs"."login"
LEFT OUTER JOIN "sessions_projects_in_sessions" ON "sessions_projects_in_sessions"."project_id" = "core_members"."project_id"
WHERE
"jobstat_jobs"."state" NOT IN (N'COMPLETETED', N'RUNNING', N'unknown')
GROUP BY
"core_members"."project_id"
) n ON s."project_id" = n."project_id"

This will also allow you further filter the resulting query like so:

rpt = Report.new 
q = rpt.query.where(rpt.n[:jobs].gt(12))
q.to_sql
#=> "...same as above...WHERE n.\"jobs\" > 12"

Rails 5.1.6 - Stack level too deep

I've got the solution, although I don't exactly understand why it was working till now.
Originally there was the below validation in the Scan model (as I posted earlier):

  with_options unless: @photo.present? do
validates :reading, presence: true
validates :reading, numericality: true
validates :reading_date, presence: true
end

In irb I managed to localize the error to this validation part. After refactoring the @photo.present? to a new method and calling that method in the validation, the problem is solved:

  with_options unless: :has_photo? do
validates :reading, presence: true
validates :reading, numericality: true
validates :reading_date, presence: true
end

def has_photo?
@photo.present?
end

Call back before save : SystemStackError: stack level too deep

Stack level too deep indicates it went to infinite loop. If you save anything in before save, after save, before create, after create, before update, after update which call callback again it will cause stack level too deep.

In above code i found that set_st_point is called in before create and saving it which caused here Stack level too deep. Data is not saving after setting also that must be some other issue that you have to check if once you set 'lonlat ' some other place it is resetting it.

Once simple fix is in after create you can say

 .update_column('lonlat',"POINT(#{longitude} #{latitude})")

update column will not call any callback this must be there in after create.



Related Topics



Leave a reply



Submit