Rails Logfiles "not opened for writing" - ruby-on-rails

I am in a process of migrating my application from ruby 1.8.7 to 1.9.3 (and later upgrading Rails). However I geht some problems with logging in 1.9.3.
By using the following code in environment.rb when console or server starts up
logfile = File.open(File.join(RAILS_ROOT,'/log/call_log.log'), 'a')
CALL_LOGGER = AuditLogger.new(logfile)
CALL_LOGGER.info "CALL_LOGGER: Server started."
I get
/usr/local/rvm/scripts/irbrc.rb:32:in `write': not opened for writing (IOError)
AuditLogger is defined as follows:
class AuditLogger < Logger
def format_message(severity, timestamp, progname, msg)
"#{timestamp.strftime("%Y-%m-%d %H:%M:%S")} #{progname} #{severity} #{msg}\n"
end
end
If I do this manually with irb, this works
1.9.3-p551 :006 > logfile = File.open(File.join('/var/my_app/log/call_log.log'), 'a')
=> #<File:/var/my_app/log/call_log.log>
=> #<AuditLogger:0x00000001ad95e8 #progname=nil, #level=0, #default_formatter=#<Logger::Formatter:0x00000001ad95c0 #datetime_format=nil>, #formatter=nil, #logdev=#<Logger::LogDevice:0x00000001ad9570 #shift_size=nil, #shift_age=nil, #filename=nil, #dev=#<File:/var/my_app/log/call_log.log>, #mutex=#<Logger::LogDevice::LogDeviceMutex:0x00000001ad9548 #mon_owner=nil, #mon_count=0, #mon_mutex=#<Mutex:0x00000001ad94f8>>>>
1.9.3-p551 :011 > CALL_LOGGER.info "CALL_LOGGER: Server started."
=> true
I suspect that the class may have been overriden by another class? So I added some code to determine the class of the file which was currently used
#file.class.ancestors
[File, IO, File::Constants, Enumerable, Object, ActiveSupport::Dependencies::Loadable, PP::ObjectMixin, JSON::Ext::Generator::GeneratorMethods::Object, Kernel, BasicObject]
#file.methods.sort
results in
[:!, :!=, :!~, :<<, :<=>, :==, :===, :=~, :__id__, :__send__, :`, :acts_like?, :advise, :all?, :any?, :as_json, :atime, :autoclose=, :autoclose?, :binmode, :binmode?, :blank?, :breakpoint, :bytes, :chars, :chmod, :chown, :chunk, :class, :class_eval, :clone, :close, :close_on_exec=, :close_on_exec?, :close_read, :close_write, :closed?, :codepoints, :collect, :collect_concat, :copy_instance_variables_from, :count, :ctime, :cycle, :daemonize, :dclone, :debugger, :define_singleton_method, :detect, :display, :drop, :drop_while, :dup, :duplicable?, :each, :each_byte, :each_char, :each_codepoint, :each_cons, :each_entry, :each_line, :each_slice, :each_with_index, :each_with_object, :enable_warnings, :entries, :enum_for, :eof, :eof?, :eql?, :equal?, :exclude?, :extend, :extend_with_included_modules_from, :extended_by, :external_encoding, :fcntl, :fdatasync, :fileno, :find, :find_all, :find_index, :first, :flat_map, :flock, :flush, :freeze, :frozen?, :fsync, :getbyte, :getc, :gets, :grep, :group_by, :hash, :html_safe?, :include?, :index_by, :initialize_clone, :initialize_dup, :inject, :inspect, :instance_eval, :instance_exec, :instance_of?, :instance_values, :instance_variable_defined?, :instance_variable_get, :instance_variable_names, :instance_variable_set, :instance_variables, :internal_encoding, :ioctl, :is_a?, :isatty, :kind_of?, :lineno, :lineno=, :lines, :load_with_new_constant_marking, :lstat, :many?, :map, :max, :max_by, :member?, :metaclass, :metaclass_with_deprecation, :metaclass_without_deprecation, :method, :methods, :min, :min_by, :minmax, :minmax_by, :mtime, :nil?, :none?, :object_id, :one?, :partition, :path, :pid, :pos, :pos=, :presence, :present?, :pretty_inspect, :pretty_print, :pretty_print_cycle, :pretty_print_inspect, :pretty_print_instance_variables, :print, :printf, :private_methods, :protected_methods, :psych_to_yaml, :psych_y, :public_method, :public_methods, :public_send, :putc, :puts, :read, :read_nonblock, :readbyte, :readchar, :readline, :readlines, :readpartial, :reduce, :reject, :remove_subclasses_of, :reopen, :require, :require_association, :require_dependency, :require_library_or_gem, :require_or_load, :respond_to?, :respond_to_missing?, :returning, :reverse_each, :rewind, :seek, :select, :send, :set_encoding, :silence_stderr, :silence_stream, :silence_warnings, :singleton_class, :singleton_methods, :size, :slice_before, :sort, :sort_by, :stat, :subclasses_of, :sum, :suppress, :syck_to_yaml, :sync, :sync=, :sysread, :sysseek, :systemu, :syswrite, :taguri, :taguri=, :taint, :tainted?, :take, :take_while, :tap, :tell, :to_a, :to_enum, :to_hash, :to_i, :to_io, :to_json, :to_param, :to_path, :to_query, :to_s, :to_set, :to_yaml, :to_yaml_properties, :to_yaml_style, :truncate, :trust, :try, :tty?, :ungetbyte, :ungetc, :unloadable, :untaint, :untrust, :untrusted?, :with_options, :write, :write_nonblock, :zip]
According to Ruby 1.9.3 File class definition there should be some methods like 'readable?', 'writable?' in the method's list. But they aren't.
Here is also my list of rubygems which may be helpful
actionmailer (2.3.18)
actionpack (2.3.18)
activerecord (2.3.18)
activeresource (2.3.18)
activesupport (2.3.18)
archive-tar-minitar (0.5.2)
bigdecimal (1.1.0)
bundler (1.7.6)
bundler-unload (1.0.2)
cgi_multipart_eof_fix (2.5.0)
charlock_holmes (0.6.9)
columnize (0.9.0)
daemons (1.0.10)
debugger-ruby_core_source (1.3.8)
eventmachine (1.0.3)
executable-hooks (1.3.2)
fastercsv (1.5.5)
fastthread (1.0.7)
gem-wrappers (1.2.7)
gem_plugin (0.2.3)
geoip-c (0.9.1)
hoe (2.7.0)
hpricot (0.8.6)
httpclient (2.3.4.1)
image_size (1.2.0)
imagesize (0.1.1)
io-console (0.3)
io-tail (0.0.3)
json (1.8.1, 1.5.5)
json_pure (1.8.2, 1.8.1)
juggernaut (2.1.1)
linecache19 (0.5.12)
macaddr (1.6.7)
mechanize (2.0.1)
memcache-client (1.8.5)
mime-types (1.16)
mini_portile (0.6.2, 0.5.2)
minitest (2.5.1)
mongrel (1.2.0.pre2)
mysql (2.9.1)
net-http-digest_auth (1.4)
net-http-persistent (1.9)
nokogiri (1.6.6.2, 1.5.0)
oj (2.5.5)
rack (1.1.6)
rails (2.3.18)
rake (10.1.1, 0.9.2.2)
rbx-require-relative (0.0.9)
rcov (0.9.11)
rdoc (4.1.1, 3.9.5)
redis (3.2.1, 3.0.7)
ruby-debug-base19 (0.11.25)
ruby-debug-base19x (0.11.31)
ruby-debug-ide (0.4.22)
ruby-ole (1.2.11.8)
ruby_core_source (0.1.5)
rubyforge (2.0.4)
rubygems-bundler (1.4.4)
rubyzip (1.1.7)
rvm (1.11.3.9)
soap4r (1.5.8)
spreadsheet (0.9.7)
svg-graph (1.0.5)
systemu (2.6.5, 2.6.4)
thin (1.6.2)
tins (0.13.2)
uuid (2.3.7)
vpim (13.11.11)
webrobots (0.1.1)
xmpp4r (0.5)
Question: Anybody knows how to overcome this issue?

You're using an old version of rails, I'm not sure how things were handled back then, but Logger.new should accept a simple filename as a string.
Forget File.open and let it figure out how to handle the file:
logfile = File.join(Rails.root, '/log/call_log.log')
CALL_LOGGER = AuditLogger.new(logfile)
CALL_LOGGER.info "CALL_LOGGER: Server started."

Related

Updated to Rails 4.0, suddenly am passing two arguments

After updating Rails gem from 3.2 to 4.0, I am getting this error:
Completed 500 Internal Server Error in 332ms
ActionView::Template::Error (wrong number of arguments (2 for 1)):
5: %th Activities
6: %th.w140
7: %tbody
8: - (list = latest_updates_list(#filter[:latest_updates_options])).each do |item|
9: %tr= latest_updates_item_helper(item)
10:
11: - if list.length == 0
app/helpers/dashboard_helper.rb:35:in `latest_updates_list'
app/views/dashboard/_index.html.haml:8:in `_app_views_dashboard__index_html_haml__3752706349525323962_70305528188080'
app/views/dashboard/index.html.haml:6:in `_app_views_dashboard_index_html_haml__2066908720777569268_70305520107720'
These are the gems that were updated:
Updated gems
Using activesupport 4.0.0 (was 3.2.18)
Using builder 3.1.4 (was 3.0.4)
Using rack 1.5.5 (was 1.4.5)
Using actionpack 4.0.0 (was 3.2.18)
Using actionmailer 4.0.0 (was 3.2.18)
Using activemodel 4.0.0 (was 3.2.18)
Using activerecord-deprecated_finders 1.0.4
Using arel 4.0.2 (was 3.0.3)
Using activerecord 4.0.0 (was 3.2.18)
Using railties 4.0.0 (was 3.2.18)
Using coffee-rails 4.0.1 (was 3.2.2)
Using postgres_ext 2.0.0 (was 1.0.0)
Using sprockets 2.8.3 (was 2.2.2)
Using rails 4.0.0 (was 3.2.18)
Using sass 3.2.19 (was 3.3.5)
Using sass-rails 4.0.5 (was 3.2.6)
This is the 'latest_updates_list' method:
def latest_updates_list(option=nil )
client_ids = current_user.actual_client_ids
services = {}
# binding.pry
Service.where(:client_id => client_ids).each{|s| services[s.id] = {:name => s.name, :frequency_name => s.frequency_short_text, :per_hour => s.per_hour?} }
#Service.where(true).each{|s| services[s.id] = {:name => s.name, :frequency_name => s.frequency_short_text, :per_hour => s.per_hour?} }
reports = []
invoices = []
tickets = []
employees = []
list = []
case option.to_sym
when :reports
reports = Report.for_latest_updates(client_ids) if (user_admin? || user_can_report?)
when :invoices
invoices = Invoice.for_latest_updates(client_ids) if (user_admin? || user_can_invoice?)
when :tickets
tickets = Ticket.for_latest_updates(client_ids) if (user_admin? || user_can_ticket?)
when :employees
employees = Employee.for_latest_updates(current_user.filter_client_id, client_ids) if user_admin?
else
reports = Report.for_latest_updates(client_ids) if (user_admin? || user_can_report?)
invoices = Invoice.for_latest_updates(client_ids) if (user_admin? || user_can_invoice?)
tickets = Ticket.for_latest_updates(client_ids) if (user_admin? || user_can_ticket?)
employees = Employee.for_latest_updates(current_user.filter_client_id, client_ids) if user_admin?
end
list += reports.collect do |r|
{
:date => r.updated_at,
:entity => 1,
:status_text => latest_update_report_status_text(r),
:reports_services_text => latest_updates_reports_services_text(r, r.reports_services),
:report_id => r.id}
end unless reports.empty?
list += invoices.collect do |i|
{
:date => i.updated_at,
:entity => 2,
:status_text => latest_update_invoice_status_text(i),
:invoice_reports_services_text => latest_updates_invoice_reports_services_text(services, i.reports),
:invoice_id => i.id}
end unless invoices.empty?
list += tickets.collect do |t|
{
:date => latest_update_ticket_date(t),
:entity => 3,
:status_text => latest_update_ticket_status_text(t),
:description => t.description_text,
:ticket_id => t.id}
end unless tickets.empty?
list += employees.collect do |e|
{
:date => e.updated_at,
:entity => 4,
:description => e.text_for_stream,
:employee_id => e.employee_id}
end unless employees.empty?
sorted_list = list.sort{|a, b| a[:date].to_i <=> b[:date].to_i}
list = sorted_list.reverse!
list = list.take(50)
end
When I comment out the first 3 'list += ....do...', then the app will load, apart from not getting the info that they get. I haven't changed any of this code, so it must be due to the gem update.
Problem solved, it was a problem with postgres_ext gem being outdated.

Active Admin Show Page for one model is not working

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.

POSTing JSON body causes Rack::QueryParser::InvalidParameterError

I'm simply trying to POST a JSON content-type http request from one Rails server to another. Putting a % character in a value string in the JSON is causing the Rack::QueryParser::InvalidParameterError on the receiving server.
On Server A, I use the httparty gem to perform a POST request w/ a JSON body
obj = {"key":"<%= #results %>"}
resp = HTTParty.post('https://test-url.com/data',
:body => obj.to_json,
:options => { :headers => { 'Content-Type' => 'application/json', 'Accept' => 'application/json' } })
On Server B, I just parse the JSON from the request body
req_body = request.body.read()
req_body_json = JSON.parse req_body
# do work with json
This process works fine unless the obj = {"key":"<%= #results %>"} contains % chars, in which case this occurs on server B:
Started POST "/data" for 10.244.1.3 at 2018-01-02 19:27:04 +0000
F, [2018-01-02T19:27:04.245275 #1] FATAL -- :
F, [2018-01-02T19:27:04.245331 #1] FATAL -- : Rack::QueryParser::InvalidParameterError (invalid %-encoding ({"key":"\u003c%)):
F, [2018-01-02T19:27:04.245358 #1] FATAL -- :
F, [2018-01-02T19:27:04.245397 #1] FATAL -- : rack (2.0.3) lib/rack/query_parser.rb:72:in `rescue in parse_nested_query'
rack (2.0.3) lib/rack/query_parser.rb:60:in `parse_nested_query'
rack (2.0.3) lib/rack/request.rb:468:in `parse_query'
rack (2.0.3) lib/rack/request.rb:343:in `POST'
actionpack (5.1.4) lib/action_dispatch/http/request.rb:362:in `block (2 levels) in POST'
actionpack (5.1.4) lib/action_dispatch/http/parameters.rb:107:in `block in parse_formatted_parameters'
actionpack (5.1.4) lib/action_dispatch/http/parameters.rb:107:in `fetch'
actionpack (5.1.4) lib/action_dispatch/http/parameters.rb:107:in `parse_formatted_parameters'
actionpack (5.1.4) lib/action_dispatch/http/request.rb:361:in `block in POST'
rack (2.0.3) lib/rack/request.rb:57:in `fetch'
rack (2.0.3) lib/rack/request.rb:57:in `fetch_header'
actionpack (5.1.4) lib/action_dispatch/http/request.rb:360:in `POST'
...
When I change obj = {"key":"<%= #results %>"} to obj = {"key":"<= #results>"} the exception does not occur.
As far I know % is a valid in JSON, what am I missing here?
Considering they way how it's implemented here: https://github.com/jnunemaker/httparty/blob/38125db0d079d52a3b0da815150fa2135bb0110d/lib/httparty.rb#L559,
Your body and headers hash keys should be siblings, try the next:
resp = HTTParty.post('https://test-url.com/data',
:body => obj.to_json,
:headers => { 'Content-Type' => 'application/json',
'Accept' => 'application/json' }
)

Cucumber can not find the input or select the dropdown box well

As usual, I use the fire-path to locate the element of my web application.
However, my testing framework is cucumber+capybara. My web application is based on ruby on rails.
Capybara support some high level keyword to do web application testing like "click_on", "select", "fill_in" and so on.
The problems I met are:
One drop-down box id is "product_id" and one value is "TEST"
However, the code like 'select "TEST", :from => "product_id"' can not work.
The step is passed, but the selection is not changed as expected.
The html code is shown bellow:
<div class="eso-greybox">
<div class="option">
<label>Product</label>
<select id="product_id" data-method="POST" data-remote="true" data-url="/automatic_test/qu_for_product" data-value="16" name="product[id]">
<option value="66">TEST</option>
<option value="55">test_data</option>
one input id is "clone-input", I try to 'fill_in "clone-input", :with => "hello" but cucumber output one error like no filed 'clone-input' found.
The html code is shown bellow:
<input id="clone-input" placeholder="test "/>
some my cucumber & capabara & rails gem versions are:
cucumber (2.4.0)
cucumber-api-steps (0.13)
cucumber-core (1.5.0)
cucumber-rails (1.4.5)
cucumber-wire (0.0.1)
capybara (2.0.3)
jquery-rails (3.1.4)
pry-rails (0.3.4)
rails (3.2.22.2)
rails-dom-testing (2.0.1)
rails-html-sanitizer (1.0.3)
rails-observers (0.1.2)
rails_autolink (1.1.4)
How to fix the two issues?
the fire-path can get the xpath, but the cucumber can not find them? why?

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

Resources