Active Admin Show Page for one model is not working - ruby-on-rails

I am integrating Active Admin into a Ruby on Rails app. I registered all my models and already set up index, filter and show for all the models. Everything is working, but for one model the admin/show page is not running.
When calling the show page from the admin/index page, I get:
NoMethodError in Admin/safts#show
Showing /Users/xxxxxx/.rvm/gems/ruby-1.8.7-p374#xxxxxx/gems/activeadmin-0.6.0/app/views/active_admin/resource/show.html.arb where line #1 raised:
undefined method `empty?' for #<Keyword:0x105498800>
Extracted source (around line #1):
1: insert_tag renderer_for(:show)
Request
Parameters:
{"id"=>"9"}
The relative entry in my log file is:
Started GET "/admin/safts/9" for 127.0.0.1 at Sun Feb 25 14:48:04 +0100 2018
Processing by Admin::SaftsController#show as HTML
Parameters: {"id"=>"9"}
[1m[35mAdminUser Load (0.6ms)[0m SELECT `admin_users`.* FROM `admin_users` WHERE `admin_users`.`id` = 2 LIMIT 1
[1m[36mSaft Load (0.2ms)[0m [1mSELECT `safts`.* FROM `safts` WHERE `safts`.`id` = ? LIMIT 1[0m [["id", "9"]]
[1m[35mKeyword Load (0.3ms)[0m SELECT `keywords`.* FROM `keywords` WHERE `keywords`.`id` = 138 LIMIT 1
Rendered /Users/xxxxxx/.rvm/gems/ruby-1.8.7-p374#xxxxxx/gems/activeadmin-0.6.0/app/views/active_admin/resource/show.html.arb (3.1ms)
Completed 500 Internal Server Error in 10ms
ActionView::Template::Error (undefined method `empty?' for #<Keyword:0x1052a0890>):
1: insert_tag renderer_for(:show)
activemodel (3.2.5) lib/active_model/attribute_methods.rb:407:in `method_missing'
activerecord (3.2.5) lib/active_record/attribute_methods.rb:149:in `method_missing'
activeadmin (0.6.0) lib/active_admin/views/pages/show.rb:38:in `default_title'
activeadmin (0.6.0) lib/active_admin/views/pages/show.rb:14:in `title'
activeadmin (0.6.0) lib/active_admin/views/pages/base.rb:25:in `build_active_admin_head'
arbre (1.0.1) lib/arbre/context.rb:92:in `with_current_arbre_element'
arbre (1.0.1) lib/arbre/element/builder_methods.rb:49:in `within'
activeadmin (0.6.0) lib/active_admin/views/pages/base.rb:24:in `build_active_admin_head'
activeadmin (0.6.0) lib/active_admin/views/pages/base.rb:9:in `build'
arbre (1.0.1) lib/arbre/element/builder_methods.rb:30:in `build_tag'
arbre (1.0.1) lib/arbre/context.rb:92:in `with_current_arbre_element'
arbre (1.0.1) lib/arbre/element/builder_methods.rb:26:in `build_tag'
arbre (1.0.1) lib/arbre/element/builder_methods.rb:39:in `insert_tag'
activeadmin (0.6.0) app/views/active_admin/resource/show.html.arb:1:in `___sers__tephan__rvm_gems_ruby_______p____somesite_gems_activeadmin_______app_views_active_admin_resource_show_html_arb___1026777847_2195984600'
arbre (1.0.1) lib/arbre/context.rb:45:in `instance_eval'
arbre (1.0.1) lib/arbre/context.rb:45:in `initialize'
activeadmin (0.6.0) app/views/active_admin/resource/show.html.arb:1:in `new'
activeadmin (0.6.0) app/views/active_admin/resource/show.html.arb:1:in `___sers__tephan__rvm_gems_ruby_______p____somesite_gems_activeadmin_______app_views_active_admin_resource_show_html_arb___1026777847_2195984600'
actionpack (3.2.5) lib/action_view/template.rb:145:in `send'
actionpack (3.2.5) lib/action_view/template.rb:145:in `render'
activesupport (3.2.5) lib/active_support/notifications.rb:125:in `instrument'
.
.
.
script/rails:6:in `gem_original_require'
script/rails:6:in `require'
script/rails:6
Rendered /Users/xxxxxx/.rvm/gems/ruby-1.8.7-p374#xxxxxx/gems/actionpack-3.2.5/lib/action_dispatch/middleware/templates/rescues/_trace.erb (0.7ms)
Rendered /Users/xxxxxx/.rvm/gems/ruby-1.8.7-p374#xxxxxx/gems/actionpack-3.2.5/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (0.6ms)
Rendered /Users/xxxxxx/.rvm/gems/ruby-1.8.7-p374#xxxxxx/gems/actionpack-3.2.5/lib/action_dispatch/middleware/templates/rescues/template_error.erb within rescues/layout (9.8ms)
The rails model is:
class Saft < ActiveRecord::Base
attr_accessible :colour, :cover_alt, :description, :number, :short, :title_id
# Associations
has_and_belongs_to_many :keywords, :join_table => "safts_keywords"
has_many :authors, :through => :texts
has_many :texts
belongs_to :title, :class_name => "Keyword", :foreign_key => "title_id"
has_one :cover
has_many :stamps
has_many :images
end
The ActiveAdmin resource is:
ActiveAdmin.register Saft do
index do
column "Issue", :number
column "Title", :title_id do |saft|
link_to saft.title.word.capitalize, saft_path(saft)
end
column :short
column :description
column :colour
column :cover_alt
default_actions
end
# Filter only by:
filter :title_id, :label => 'Title', :as => :select, :collection => Saft.all.map{|u| ["#{u.title.word.capitalize}", u.id]}
filter :short
form do |f|
f.inputs "Saft Details" do
f.input :number, :label => "Number of issue"
f.input :title_id, :label => 'Title', :as => :select, :collection => Keyword.all.map{|u| ["#{u.word.capitalize}", u.id]}
f.input :short
f.input :description
f.input :colour, :label => "Colour (in hex)"
f.input :cover_alt
end
f.actions
end
show do
panel "Saft Details" do
attributes_table_for saft do
row :id
row :number
row :title_id
row :short
row :description
row :colour
row :cover_alt
row :created_at
row :updated_at
end
end
active_admin_comments
end
end
Just for context: SAFT is a magazine, with texts, images, authors, etc. All the other resources are working well in Admin. Only the show page of SAFT is not working. What could it be?

Your log entry says Keyword does not respond to empty? in Pages::Show#default_title.
default_title calls display_name, have you overridden display_name_methods? In this case you can remove :title
In config/initializers/active_admin:
config.display_name_methods = [ :display_name,
:full_name,
:name,
:username,
:login,
:email,
:to_s ]
Perhaps better in this case you can also try setting the title explicitly, eg.
show title: :short do ...
I notice you are on very old versions of Rails and ActiveAdmin, I hope you will consider upgrading.

I was able to solve the problem, which is related to the associations.
The DisplayHelper Module of the gem has to be modified as follows:
module ActiveAdmin
module ViewHelpers
module DisplayHelper
# Attempts to call any known display name methods on the resource.
# See the setting in `application.rb` for the list of methods and their priority.
def display_name(resource)
resource.send display_name_method_for resource
end
# Looks up and caches the first available display name method.
def display_name_method_for(resource)
##display_name_methods_cache ||= {}
##display_name_methods_cache[resource.class] ||= begin
methods = active_admin_application.display_name_methods - association_methods_for(resource)
methods.detect{ |method| resource.respond_to? method }
end
end
# To prevent conflicts, we exclude any methods that happen to be associations.
def association_methods_for(resource)
return [] unless resource.class.respond_to? :reflect_on_all_associations
resource.class.reflect_on_all_associations.map(&:name)
end
# Return a pretty string for any object
# Date Time are formatted via #localize with :format => :long
# ActiveRecord objects are formatted via #auto_link
# We attempt to #display_name of any other objects
def pretty_format(object)
case object
when String
object
when Arbre::Element
object
when Date, Time
localize(object, :format => :long)
when ActiveRecord::Base
auto_link(object)
else
display_name(object)
end
end
end
end
end
This is because in the SAFT model there is an association with the name title, which goes into conflict with the display_name_method.

Related

Why does `has_many` association generate an error when using the `:dependent => :restrict`option?

Ruby 2.2 , Rails 3.21
I got the following error when I try to destroy my object.
This happen with any object whose model has an association with :dependent => :restrict option
This error is strange because it suggests a NIL object, though when I log the class and Id of the related object just before the error, it shows the expected class with correct ID.
NoMethodError in Projects::ProjClefsRepartitionController#destroy
undefined method `name' for nil:NilClass
app/controllers/projects/proj_clefs_repartition_controller.rb:322:in
block in destroy
app/controllers/projects/proj_clefs_repartition_controller.rb:315:in destroy
This is the related code of the ProjClefsRepartitionController controller :
294# def destroy
295#
296# messages = {}
297#
298# # Create the #proj_clef_repartition objet
299# unless creer_instance_objet_et_render_parent_si_impossible(ProjClefRepartition, params[:id], params[:proj_sous_projet_id], [{:proj_sous_projet => [:proj_charges, {:proj_projet => {:proj_mesure => :proj_paquet_mesures}}]}]) then
300#
301# enregistrement_ok = false
302#
303# #objet_de_l_erreur = #proj_clef_repartition
304# #proj_sous_projet = #proj_clef_repartition.proj_sous_projet
305# #proj_projet = #proj_sous_projet.proj_projet
306# #proj_mesure = #proj_projet.proj_mesure
307# #proj_paquet_mesures = #proj_mesure.proj_paquet_mesures
308# #hist_version_sous_projet = HistVersionSousProjet.where(:proj_sous_projet_id => #proj_sous_projet.id).order{version.desc}.limit(1)[0]
309#
310# #proj_clefs_repartition = #proj_sous_projet.proj_clefs_repartition
311# #proj_charges = #proj_sous_projet.proj_charges
312# #total_charges = BigDecimal.new('0', 18)
313#
314# # =================== DEBUT DE LA TRANSACTION ===================
315# ProjClefRepartition.transaction do
316#
317#
318# if sauver_version(#proj_clef_repartition, messages, nil, 3, nil, true) then
319#
320# logger.debug "#{#proj_clef_repartition.blank?}"
321# logger.debug "#{#proj_clef_repartition.class} (#{#proj_clef_repartition.id})"
322# if #proj_clef_repartition.destroy then
323# ajouter_message(t('activerecord.successful.messages.deleted', :model => ProjClefRepartition.model_name.human), :success, messages)
324# enregistrement_ok = true
325# else
326# ajouter_message(t('activerecord.warning.messages.deleted', :model => ProjClefRepartition.model_name.human), :alert, messages)
327# end # proj_clef_repartition.destroy
328#
329# end # sauver_version(#proj_clef_repartition, messages, nil, 3, nil, true)
330#
331#
332# raise ActiveRecord::Rollback unless enregistrement_ok
333#
334# end # ProjClefRepartition.transaction
335# # =================== FIN DE LA TRANSACTION ===================
336#
337#
338# afficher_maintenant(messages)
339#
340# render 'projects/proj_sous_projets/show'
341#
342# end # creer_instance_objet_et_render_parent_si_impossible(ProjClefRepartition, params[:id], params[:proj_sous_projet_id])
343#
344#
345# rescue ActiveRecord::StatementInvalid => exception
346#
347#
348#
349#
350#
351# #hist_sous_projet = #hist_version_sous_projet.hist_sous_projet
352# ajouter_message(t('activerecord.warning.messages.invalid_db_statement'), :error, messages)
353# ajouter_erreur_concernant_exception_statement_invalid(exception, #objet_de_l_erreur)
354# afficher_maintenant(messages)
355# render 'projects/proj_sous_projets/show'
356#
357#
358# rescue ActiveRecord::DeleteRestrictionError => exception
359#
360#
361# #hist_sous_projet = #hist_version_sous_projet.hist_sous_projet
362#
363# ajouter_message(t('activerecord.warning.messages.delete_restriction', :model => ProjClefRepartition.model_name.human), :error, messages)
364# afficher_maintenant(messages)
365# render 'projects/proj_sous_projets/show'
366#
367# end # destroy
Following is an extract of the log that is related to the error.
You can see that the object is not blank and has a class with a valid ID.
It shows false for #proj_clef_repartition.blank? logging.
It shows ProjClefRepartition (96) for #proj_clef_repartition.class and #proj_clef_repartition.id
QUITTING ||| historisation_nouvelle_version_avec_origine
(pub_modification_id = 2) ||| ===>
output_hash[:id_hist_origine_modification] = 1202 (0.4ms) SELECT
COUNT(*) FROM "proj_charges" WHERE
"proj_charges"."proj_clef_repartition_id" = 96
false
ProjClefRepartition (96)
(0.4ms) ROLLBACK
Completed 500 Internal Server Error in 298.9ms
NoMethodError (undefined method name' for nil:NilClass):
app/controllers/projects/proj_clefs_repartition_controller.rb:322:in
block in destroy'
app/controllers/projects/proj_clefs_repartition_controller.rb:315:in
`destroy'
Rendered
/home/douglas/.rvm/gems/ruby-2.2.0#rail3/gems/actionpack-3.2.21/lib/action_dispatch/middleware/templates/rescues/_trace.erb
(2.4ms) Rendered
/home/douglas/.rvm/gems/ruby-2.2.0#rail3/gems/actionpack-3.2.21/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb
(1.9ms) Rendered
/home/douglas/.rvm/gems/ruby-2.2.0#rail3/gems/actionpack-3.2.21/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb
within rescues/layout (21.8ms)
It does not make sense. I checked the full trace, and noticed that the "Nil" object error which happened in active_record has_many association.
Here it is the full trace :
NoMethodError in Projects::ProjClefsRepartitionController#destroy
undefined method `name' for nil:NilClass Rails.root: /var/www/odpf
Application Trace | Framework Trace | Full Trace
activerecord (3.2.21)
lib/active_record/associations/has_many_association.rb:58:in
`cached_counter_attribute_name'
activerecord (3.2.21)
lib/active_record/associations/has_many_association.rb:54:in
`has_cached_counter?'
activerecord (3.2.21)
lib/active_record/associations/has_many_association.rb:37:in
`count_records'
activerecord (3.2.21)
lib/active_record/associations/collection_association.rb:261:in `size'
activerecord (3.2.21)
lib/active_record/associations/collection_association.rb:280:in
`empty?'
activerecord (3.2.21)
lib/active_record/associations/collection_proxy.rb:46:in `empty?'
activerecord (3.2.21)
lib/active_record/associations/builder/has_many.rb:63:in `block in
define_restrict_dependency_method'
activesupport (3.2.21) lib/active_support/callbacks.rb:418:in
`_run__1417810521555210605__destroy__1154072583585286936__callbacks'
activesupport (3.2.21) lib/active_support/callbacks.rb:405:in
`__run_callback'
activesupport (3.2.21) lib/active_support/callbacks.rb:385:in
`_run_destroy_callbacks'
activesupport (3.2.21) lib/active_support/callbacks.rb:81:in
`run_callbacks'
activerecord (3.2.21) lib/active_record/callbacks.rb:254:in `destroy'
activerecord (3.2.21) lib/active_record/transactions.rb:254:in `block
in destroy'
activerecord (3.2.21) lib/active_record/transactions.rb:313:in `block
in with_transaction_returning_status'
activerecord (3.2.21)
lib/active_record/connection_adapters/abstract/database_statements.rb:192:in
`transaction'
activerecord (3.2.21) lib/active_record/transactions.rb:208:in
`transaction'
activerecord (3.2.21) lib/active_record/transactions.rb:311:in
`with_transaction_returning_status'
activerecord (3.2.21) lib/active_record/transactions.rb:254:in
`destroy'
app/controllers/projects/proj_clefs_repartition_controller.rb:322:in
`block in destroy'
activerecord (3.2.21)
lib/active_record/connection_adapters/abstract/database_statements.rb:192:in
`transaction'
activerecord (3.2.21) lib/active_record/transactions.rb:208:in
`transaction'
app/controllers/projects/proj_clefs_repartition_controller.rb:315:in
`destroy'
So I checked my model ProjClefRepartition.
I made a successful test without error when I removed the , :dependent => :restrict part of the two line :
has_many :proj_contributions, :dependent => :restrict
has_many :proj_charges, :dependent => :restrict
require Rails.root.to_s + '/lib/opf_modules/opf_outils_models.rb'
class ProjClefRepartition < ActiveRecord::Base
include OutilsModels
# Renforcement de la sécurité avec declarative_authorization Gem
using_access_control
# Modifier les attributs contenant des string vides en des nil
before_validation :blank_string_attributes_to_nil
attr_accessible :code, :designation, :proj_sous_projet_id, :motivation, :pub_modification_id
validates :code, :designation, :proj_sous_projet_id, :pub_modification_id, :admin_utilisateur_id, :presence => true
attr_accessor :montant_contributions_total
validates :code, :length => { :in => 2..19 }, :uniqueness => { :case_sensitive => false }
validates :designation, :length => { :in => 2..60 }
validates :motivation, :length => { :in => 5..600 }, :allow_blank => true
validate :clef_repartition_exclusive_a_un_unique_sous_projet
belongs_to :proj_sous_projet
belongs_to :pub_modification
belongs_to :admin_utilisateur
has_many :proj_contributions, :dependent => :restrict
has_many :proj_charges, :dependent => :restrict
has_many :hist_versions_clefs_repartition, :class_name => HistVersionClefRepartition
# Méthode utilisée par la collection_select box
def texte_pour_collection_select
# Groupé les attributs afin d'améliorer la compréhension de l'utilisateur lors du choix par la select box
self.code + ' - ' + self.designation
end
# -------------------------------------------------------------
# Validations speciale
# -------------------------------------------------------------
private
def clef_repartition_exclusive_a_un_unique_sous_projet
# Lors de la création d'une nouvelle clé de répartition, l'ID est nil, et il n'y a aucun risque que la clef soit déjà utilisée par une charge
unless id.nil? then
# Trouver toutes les charges utilisant cette clé de répartition
proj_charges = ProjCharge.where(:proj_clef_repartition_id => id)
proj_charges.each do |c|
if c.proj_sous_projet_id != proj_sous_projet_id then
errors.add(:proj_sous_projet_id, I18n.t('activemodel.warning.messages.reaffectation_impossible', :modele_enfant => I18n.t('projects.proj_charges.model'), :modele_parent => I18n.t('projects.proj_sous_projets.model'), :modele => I18n.t('projects.proj_clefs_repartition.model')))
break
end # c.proj_sous_projet_id != proj_sous_projet_id
end # proj_charges.each
end # id.nil?
end # clef_repartition_exclusive_a_un_unique_sous_projet
end
So I'm really wondering if this could be a bug in Ruby on Rails version 3.21.
Any help is more than welcome.
=== EDIT ===
The two other associated models (proj_charge and proj_contribution) do have the following line :
belongs_to :proj_clef_repartition

stack level to deep Rails 2.3.14

I'm developing a plugin for a management framework and when I start the webrick server in the development mode, a strange error raises(stack level too deep). It happens when an action (e.g. the show action) starts to render a template. Unfortunately i have no idea why this is happen.
SystemStackError in Stories#show
Showing vendor/plugins/stories/app/views/stories/show.rhtml where line #5 raised:
stack level too deep
Extracted source (around line #5):
5: link_to_if_authorized 'aa', {:controller => "stories", :action => "index", :id => #story.id, :project_id => #story.project.id}, :title => l(:view_story), :class => 'icon icon-zoom-out'
6: link_to_if_authorized 'bb', {:controller => "stories", :action => "edit", :id => #story.id, :project_id => #story.project.id}, :title => l(:button_edit), :class => 'icon icon-edit'
7: link_to 'bb', {:id => #story.id, :project_id => #story.project.id}, :confirm => 'Really delete?', :method => :delete, :class => 'icon icon-del' if User.current.allowed_to? (:delete_stories, #project)
RAILS_ROOT: /home/haendwic/Documents/Aptana Studio 3 Workspace/1.4-stable-SVN
Application Trace | Framework Trace | Full Trace
/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/attribute_methods.rb:248:in method_missing'
/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/attribute_methods.rb:249:in method_missing'
/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/associations /association_proxy.rb:215:in send'
/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/associations/association_proxy.rb:215:in method_missing'
/home/haendwic/Documents/Aptana Studio 3 Workspace/1.4-stable-SVN/vendor/plugins/stories/app/views/stories/show.rhtml:5:in _run_rhtml_vendor47plugins47stories47app47views47stories47show46rhtml'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/renderable.rb:34:in send'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/renderable.rb:34:in render'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/base.rb:306:in with_template'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/renderable.rb:30:in render'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/template.rb:205:in render_template'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/base.rb:265:in render'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/base.rb:348:in _render_with_layout'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_view/base.rb:262:in render'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:1252:in render_for_file'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:936:in render_without_benchmark'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/benchmarking.rb:51:in render'
/var/lib/gems/1.8/gems/activesupport-2.3.14/lib/active_support/core_ext/benchmark.rb:17:in ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in realtime'
/var/lib/gems/1.8/gems/activesupport-2.3.14/lib/active_support/core_ext/benchmark.rb:17:in ms'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/benchmarking.rb:51:in render'
/home/haendwic/Documents/Aptana Studio 3 Workspace/1.4-stable-SVN/vendor/plugins/stories/app/controllers/stories_controller.rb:104:in show'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:135:in call'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:135:in custom'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:179:in call'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:179:in respond'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:173:in each'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:173:in respond'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/mime_responds.rb:107:in respond_to'
/home/haendwic/Documents/Aptana Studio 3 Workspace/1.4-stable-SVN/vendor/plugins/stories/app/controllers/stories_controller.rb:102:in show'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:1333:in send'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:1333:in perform_action_without_filters'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/filters.rb:617:in call_filters'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/filters.rb:610:in perform_action_without_benchmark'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/benchmarking.rb:68:in perform_action_without_rescue'
/var/lib/gems/1.8/gems/activesupport-2.3.14/lib/active_support/core_ext/benchmark.rb:17:in ms'
/usr/lib/ruby/1.8/benchmark.rb:308:in realtime'
/var/lib/gems/1.8/gems/activesupport-2.3.14/lib/active_support/core_ext/benchmark.rb:17:in ms'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/benchmarking.rb:68:in perform_action_without_rescue'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/rescue.rb:160:in perform_action_without_flash'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/flash.rb:151:in perform_action'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:532:in send'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:532:in process_without_filters'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/filters.rb:606:in process'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:391:in process'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/base.rb:386:in call'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/routing/route_set.rb:438:in call'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/dispatcher.rb:87:in dispatch'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/dispatcher.rb:121:in _call'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/dispatcher.rb:130:in build_middleware_stack'
/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/query_cache.rb:29:in call'
/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/query_cache.rb:29:in call'
/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in cache'
/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/query_cache.rb:9:in cache'
/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/query_cache.rb:28:in call'
/var/lib/gems/1.8/gems/activerecord-2.3.14/lib/active_record/connection_adapters/abstract/connection_pool.rb:361:in call'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/string_coercion.rb:25:in call'
/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/head.rb:9:in call'
/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/methodoverride.rb:24:in call'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/params_parser.rb:15:in call'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/session /cookie_store.rb:99:in call'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/failsafe.rb:26:in call'
/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/lock.rb:11:in call'
/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/lock.rb:11:in synchronize'
/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/lock.rb:11:in call'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/dispatcher.rb:114:in call'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/reloader.rb:34:in run'
/var/lib/gems/1.8/gems/actionpack-2.3.14/lib/action_controller/dispatcher.rb:108:in call'
/var/lib/gems/1.8/gems/rails-2.3.14/lib/rails/rack/static.rb:31:in call'
/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/urlmap.rb:47:in call'
/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/urlmap.rb:41:in each'
/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/urlmap.rb:41:in call'
/var/lib/gems/1.8/gems/rails-2.3.14/lib/rails/rack/log_tailer.rb:17:in call'
/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/content_length.rb:13:in call'
/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/handler/webrick.rb:48:in service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in start'
/var/lib/gems/1.8/gems/rack-1.1.3/lib/rack/handler/webrick.rb:14:in run'
/var/lib/gems/1.8/gems/rails-2.3.14/lib/commands/server.rb:111
script/server:3:in require'
script/server:3
Request
Parameters:
{"project_id"=>"1",
"id"=>"2"}
Show session dump
Response
Headers:
{"Cache-Control"=>"no-cache",
"Content-Type"=>"text/html"}
and here is the action from the controller
def show
#edit_allowed = User.current.allowed_to?(:edit_stories, #project)
respond_to do |format|
format.html {
render :template => 'stories/show'
}
format.api
format.pdf { send_data(story_to_pdf(#story), :type => 'application/pdf', :filename => "#{#project.identifier}-#{#story.id}.pdf") }
end
end
and at last a part of the view
link_to_if_authorized 'aa', {:controller => "stories", :action => "index", :id => #story.id, :project_id => #story.project.id}, :title => l(:view_story), :class => 'icon icon-zoom-out'
link_to_if_authorized 'bb', {:controller => "stories", :action => "edit", :id => #story.id, :project_id => #story.project.id}, :title => l(:button_edit), :class => 'icon icon-edit'
link_to 'bb', {:id => #story.id, :project_id => #story.project.id}, :confirm => 'Really delete?', :method => :delete, :class => 'icon icon-del' if User.current.allowed_to?(:delete_stories, #project)
Maybe it's important to say, that in the production mode the plugin is stable and routes the actions (incl. show) correctly
This is typically caused by you (or others) patching core models (probably the Project model) from a plugin without taking the rails reloader into account.
If you override methods (e.g. using alias_method_chain) and your patch is loaded twice, you can easily create an infinite loop when calling the old method.
# This is our initial class
class MyClass
def foo
puts "original foo"
end
end
module Patch
def self.included(base)
base.alias_method_chain :foo, :feature
end
def foo_with_feature
foo_without_feature # call the "original" method
puts "foo with feature"
end
end
# patch the class
MyClass.send(:include, Patch)
# Now call the patched method
MyClass.new.foo
# prints:
# original foo
# foo with feature
foo now refers to the method foo_with_feature while the original foo method now is accessible from foo_without_feature
All right, until now everything looked good. Now let's see what happens, if we load our patch again
# patch again
MyClass.send(:include, Patch)
# And call the method again
MyClass.new.foo
# SystemStackError: stack level too deep
# from (irb):7:in `foo_without_feature'
# from (irb):7:in `foo'
# from (irb):27
You see a SystemStackError caused by an infinite loop. This is because after the second loading of the patch, foo_without_feature now refers to the foo_with_feature method from the first patch. When calling it, it will over and over again call foo_without_feature until the stack is full.
You said that it only crashes on the second request. This is exactly the typical behavior when something is odd on the class reloader. By default, Rails will reload all classes on every request in development mode but only once in production mode.
Taming the rails reloader is a bit tricky sometimes. As some general guidelines, you should
use require_dependency instead of require when loading patches
load your patches using Dispatcher.to_prepare
always declare the patched classes unloadable
The most critical part is using Dispatcher.to_prepare. It is a callback which is called once in production mode and before each request in development mode and is thus the ideal place for loading patches.
As a side note though: When using Redmine 2 (or the upcoming ChiliProject 4), i.e. Rails 3, the class patching will be rather different from this approach - most probably easier.
The "stack level too deep" error means that you have a stack overflow (it happens often enough to have a site named after it). That occurs when a function calls itself indefinitely or when two functions call each other indefinitely.
Your error happens on line 5, so I'd check the source for link_to_if_authorized. Something in there is causing an infinite loop.

Can't do geo query on embedded document using Mongoid and Geocoder

(Ruby 1.9.3, MongoDB 2.0.4, Rails 3.2, Mongoid 2.4, Geocoder 1.1.1)
I have the following models:
class Company
include Mongoid::Document
embeds_one :office
index [[ "office.coordinates", Mongo::GEO2D ]]
end
class Office
include Mongoid::Document
include Geocoder::Model::Mongoid
geocoded_by :address
field :city, :type => String
field :state, :type => String
field :coordinates, :type => Array
embedded_in :company
after_validation :geocode
def address
"#{city}, #{state}"
end
end
I do this in the console:
> c = Company.new
=> #<Company _id: 4f885aa56d20f03898000003, _type: nil>
> c.office = Office.new(:city => "San Francisco", :state => "CA")
=> #<Office _id: 4f885ab66d20f03898000004, _type: nil, city: "San Francisco", state: "CA", coordinates: nil>
> c.save
=> true
So far so good. But then I try to retrieve the company by doing a geoquery on its embedded document (office):
> Company.where(:office.near => Company.first.office.to_coordinates).first
Mongo::OperationFailure: can't find special index: 2d for: { office: { $near: [ -122.4194155, 37.7749295 ] } }
from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongo-1.6.2/lib/mongo/cursor.rb:144:in `next'
from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongo-1.6.2/lib/mongo/collection.rb:288:in `find_one'
from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongoid-2.4.8/lib/mongoid/collections/master.rb:25:in `block in find_one'
from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongoid-2.4.8/lib/mongoid/collections/retry.rb:29:in `retry_on_connection_failure'
from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongoid-2.4.8/lib/mongoid/collections/master.rb:24:in `find_one'
from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongoid-2.4.8/lib/mongoid/collection.rb:60:in `find_one'
from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongoid-2.4.8/lib/mongoid/contexts/mongo.rb:203:in `first'
from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/mongoid-2.4.8/lib/mongoid/criteria.rb:45:in `first'
from (irb):2
from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.3/lib/rails/commands/console.rb:47:in `start'
from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.3/lib/rails/commands/console.rb:8:in `start'
from /Users/raphael/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.3/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
What am I doing wrong? I've run rake db:mongoid:create_indexes.
You need to run the query against the embedded field:
Company.where(:'office.coordinates'.near => Company.first.office.to_coordinates).first
If you want to leverage the near scope created by the geocoder gem under Office, you can do something like the following:
# in Company.rb
self.near(office, radius = 20, conditions = {})
self.where(conditions).tap do |criteria|
near_criteria = Office.scopes[:near].conditions.call(office, radius)
criteria.selector[:'office.coordinates'] = near_criteria.selector[:coordinates]
end
end
This creates Company#near which takes an Office object. It will inject the query created by the Office#near scope into a query for a company.

Writing new embedded document in Mongoid fails mysteriously

I'm trying to embed a new document in a previously existing document. When the object was created, the root document looked like this:
class MongoPoll
include Mongoid::Document
embeds_one :region_count, :as => :voteable, :class_name => 'VoteCount'
I've added a few new embedded documents of the same class:
embeds_one :browser_count, :as => :voteable, :class_name => 'VoteCount'
embeds_one :os_count, :as => :voteable, :class_name => 'VoteCount'
The VoteCount class looks like:
class VoteCount
include Mongoid::Document
embedded_in :voteable, :polymorphic => true
When I create new documents from scratch, I create the embedded documents in a before_create handler, and it works fine:
self.region_count = VoteCount.new
self.browser_count = VoteCount.new
self.os_count = VoteCount.new
However, for migrating my old documents, I try to do the same assignment (poll.os_count = VoteCount.new; poll.save) and it fails silently for os_count (but oddly not for browser_count). When I try saving using update_attribute or poll['os_count'] = VoteCount.new from rails console, I get stacktraces that look like the following:
BSON::InvalidDocument: Cannot serialize an object of class VoteCount into BSON.
from /Library/Ruby/Gems/1.8/gems/bson-1.4.0/lib/../lib/bson/bson_c.rb:24:in `serialize'
from /Library/Ruby/Gems/1.8/gems/bson-1.4.0/lib/../lib/bson/bson_c.rb:24:in `serialize'
from /Library/Ruby/Gems/1.8/gems/mongo-1.4.0/lib/../lib/mongo/collection.rb:426:in `update'
from /Library/Ruby/Gems/1.8/gems/mongoid-2.2.2/lib/mongoid/collections/master.rb:19:in `update'
from /Library/Ruby/Gems/1.8/gems/mongoid-2.2.2/lib/mongoid/collections/retry.rb:29:in `retry_on_connection_failure'
from /Library/Ruby/Gems/1.8/gems/mongoid-2.2.2/lib/mongoid/collections/master.rb:18:in `update'
from /Library/Ruby/Gems/1.8/gems/mongoid-2.2.2/lib/mongoid/collection.rb:149:in `update'
from /Library/Ruby/Gems/1.8/gems/mongoid-2.2.2/lib/mongoid/persistence/operations/update.rb:45:in `persist'
from /Library/Ruby/Gems/1.8/gems/mongoid-2.2.2/lib/mongoid/persistence/modification.rb:25:in `prepare'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.9/lib/active_support/callbacks.rb:414:in `_run_update_callbacks'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.9/lib/active_support/callbacks.rb:94:in `send'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.9/lib/active_support/callbacks.rb:94:in `run_callbacks'
from /Library/Ruby/Gems/1.8/gems/mongoid-2.2.2/lib/mongoid/persistence/modification.rb:24:in `prepare'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.9/lib/active_support/callbacks.rb:414:in `_run_save_callbacks'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.9/lib/active_support/callbacks.rb:94:in `send'
from /Library/Ruby/Gems/1.8/gems/activesupport-3.0.9/lib/active_support/callbacks.rb:94:in `run_callbacks'
from /Library/Ruby/Gems/1.8/gems/mongoid-2.2.2/lib/mongoid/persistence/modification.rb:23:in `prepare'
from /Library/Ruby/Gems/1.8/gems/mongoid-2.2.2/lib/mongoid/persistence/operations/update.rb:43:in `persist'
from /Library/Ruby/Gems/1.8/gems/mongoid-2.2.2/lib/mongoid/persistence.rb:86:in `update'
from /Library/Ruby/Gems/1.8/gems/mongoid-2.2.2/lib/mongoid/persistence.rb:151:in `save'
from (irb):5
Any idea what might be wrong here?

Rails error with validation and multiple models, can't convert HashWithIndifferentAccess into String

I haven't used rails since version 1.2 or so and a few things have changed. I have an issue where I am trying to save an empty model to get validation errors on attributes using :validates_presence_of and instead I am getting the error 'can't convert HashWithIndifferentAccess into String'. I will attempt to simplify my code to get the point across as tersely as possible...
my model:
class Project < ActiveRecord::Base
validates_presence_of :title, :description
validates_uniqueness_of :title
has_one :address
accepts_nested_attributes_for :address, :allow_destroy => true
end
Child model:
class Address < ActiveRecord::Base
validates_presence_of :title, :street
belongs_to :project
end
controller:
class ProjectsController < ApplicationController
def create
#project = Project.new(params[:project])
if #project.save
flash[:notice] = #project.title + ' successfully created'
redirect_to projects_path
else
render :action => 'new'
end
end
end
view:
<%= error_messages_for 'project' %>
<% form_for #project do |f| %>
<table width="100%" cellpadding="3" cellspacing="0">
<tr>
<td class="adminlabel">
<label for="Title">Title</label>
</td>
<td class="adminbody">
<%= f.text_field :title %>
</td>
</tr>
.....
<% f.fields_for :address do |address| %>
....
This code adds and updates just fine as long as I fill in all the required fields, if I leave any blank I get the error mentioned above, not the most graceful way of alerting users there is an issue ;)
Request params:
{"commit"=>"Save",
"project"=>{"title"=>"",
"notes"=>"",
"description"=>"",
"address_attributes"=>{"city"=>"",
"zip"=>"",
"title"=>"",
"country"=>"",
"suite"=>"",
"street"=>"",
"state"=>""}},
"authenticity_token"=>"iNPQZrf/oBv22vaI0toTGhknwx0aAU3BSvnIh6qgYQ8="}
I have been searching for days and am at my wits end, if anyone can shed a little light on this for me I would greatly appreciate it.
Thanks in advance!
Brendan
PS - the stack trace as requested:
.../app/controllers/projects_controller.rb:27:in `+'
.../app/controllers/projects_controller.rb:27:in `create'
../actionpack-2.3.4/lib/action_controller/base.rb:1331:in `send'
../actionpack-2.3.4/lib/action_controller/base.rb:1331:in `perform_action_without_filters'
../actionpack-2.3.4/lib/action_controller/filters.rb:617:in `call_filters'
../actionpack-2.3.4/lib/action_controller/filters.rb:610:in `perform_action_without_benchmark'
../actionpack-2.3.4/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
../activesupport-2.3.4/lib/active_support/core_ext/benchmark.rb:17:in `ms'
../activesupport-2.3.4/lib/active_support/core_ext/benchmark.rb:10:in `realtime'
../activesupport-2.3.4/lib/active_support/core_ext/benchmark.rb:17:in `ms'
../actionpack-2.3.4/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
../actionpack-2.3.4/lib/action_controller/rescue.rb:160:in `perform_action_without_flash'
../actionpack-2.3.4/lib/action_controller/flash.rb:146:in `perform_action'
../actionpack-2.3.4/lib/action_controller/base.rb:532:in `send'
../actionpack-2.3.4/lib/action_controller/base.rb:532:in `process_without_filters'
../actionpack-2.3.4/lib/action_controller/filters.rb:606:in `process'
../actionpack-2.3.4/lib/action_controller/base.rb:391:in `process'
../actionpack-2.3.4/lib/action_controller/base.rb:386:in `call'
../actionpack-2.3.4/lib/action_controller/routing/route_set.rb:437:in `call'
../actionpack-2.3.4/lib/action_controller/dispatcher.rb:87:in `dispatch'
../actionpack-2.3.4/lib/action_controller/dispatcher.rb:121:in `_call'
../actionpack-2.3.4/lib/action_controller/dispatcher.rb:130:in `build_middleware_stack'
../activerecord-2.3.4/lib/active_record/query_cache.rb:29:in `call'
../activerecord-2.3.4/lib/active_record/query_cache.rb:29:in `call'
../activerecord-2.3.4/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
..activerecord-2.3.4/lib/active_record/query_cache.rb:9:in `cache'
../activerecord-2.3.4/lib/active_record/query_cache.rb:28:in `call'
../activerecord-2.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:361:in `call'
../rack-1.0.1/lib/rack/head.rb:9:in `call'
../rack-1.0.1/lib/rack/methodoverride.rb:24:in `call'
../actionpack-2.3.4/lib/action_controller/params_parser.rb:15:in `call'
../actionpack-2.3.4/lib/action_controller/session/cookie_store.rb:93:in `call'
../actionpack-2.3.4/lib/action_controller/failsafe.rb:26:in `call'
../rack-1.0.1/lib/rack/lock.rb:11:in `call'
../rack-1.0.1/lib/rack/lock.rb:11:in `synchronize'
../rack-1.0.1/lib/rack/lock.rb:11:in `call'
../actionpack-2.3.4/lib/action_controller/dispatcher.rb:114:in `call'
../actionpack-2.3.4/lib/action_controller/reloader.rb:34:in `run'
../actionpack-2.3.4/lib/action_controller/dispatcher.rb:108:in `call'
../rails-2.3.4/lib/rails/rack/static.rb:31:in `call'
../rack-1.0.1/lib/rack/urlmap.rb:46:in `call'
../rack-1.0.1/lib/rack/urlmap.rb:40:in `each'
../rack-1.0.1/lib/rack/urlmap.rb:40:in `call'
../rails-2.3.4/lib/rails/rack/log_tailer.rb:17:in `call'
../rack-1.0.1/lib/rack/content_length.rb:13:in `call'
../rack-1.0.1/lib/rack/chunked.rb:15:in `call'
../rack-1.0.1/lib/rack/handler/mongrel.rb:64:in `process'
..... etc.
A bit lengthy, sorry ;)
Try adding
#project.address.build
to your controller. You need to instantiate the address object.
The trace doesn't lie. You're having issues with a line 27. The code you posted doesn't have 37 lines, but based on the trace I'm willing to bet it's this line. Because none others have have a '+'. If there was an implicit + its caller would've been listed in the trace.
flash[:notice] = #project.title + ' successfully created'
It's odd that it's reaching that point based on your validations. validates_presence_of should add errors on attributes that are either nil, false or "". Does the validation fail as expected when run in the console?
Here's a console friendly version of your code that could be used to track down your issue. You should be able to just paste it into the console to help track down your issue.
params = {
"project"=> {
"title"=>"", "notes"=>"","description"=>"",
"address_attributes"=>{
"city"=>"", "zip"=>"","title"=>"","country"=>"",
"suite"=>"","street"=>"","state"=>""
}
}
flash = {}
#project = Project.new(params[:project])
if #project.save
flash[:notice] = #project.title + ' successfully created'
puts "Saved. Flash: #{flash[:notice]}"
else
puts "validations failed:"
puts #project.errors.full_messages.map{|m| "\t#{m}"}.join("\n")
end

Resources