maxrossello / redmine_app_timesheets

A true timesheet plugin using orders, not bound to timelogs over issues
GNU General Public License v2.0
32 stars 10 forks source link

Timesheet app not working after deletion of orders #23

Closed danielwagn3r closed 10 years ago

danielwagn3r commented 10 years ago

After creating an order the timesheet cannot be opened anymore. We get an Redmine 500 error.

In the production.log I found the following:

NoMethodError (undefined method `name' for nil:NilClass):
  plugins/redmine_app_timesheets/app/controllers/timesheets_controller.rb:252:in `block in get_timelogs'
  plugins/redmine_app_timesheets/app/controllers/timesheets_controller.rb:252:in `each'
  plugins/redmine_app_timesheets/app/controllers/timesheets_controller.rb:252:in `sort_by'
  plugins/redmine_app_timesheets/app/controllers/timesheets_controller.rb:252:in `get_timelogs'
  vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.17/lib/active_support/callbacks.rb:517:in `_run__62742077__process_action__922996282__callbacks'
  vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.17/lib/active_support/callbacks.rb:405:in `__run_callback'
  vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.17/lib/active_support/callbacks.rb:385:in `_run_process_action_callbacks'
  vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.17/lib/active_support/callbacks.rb:81:in `run_callbacks'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/abstract_controller/callbacks.rb:17:in `process_action'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_controller/metal/rescue.rb:29:in `process_action'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'
  vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.17/lib/active_support/notifications.rb:123:in `block in instrument'
  vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.17/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.17/lib/active_support/notifications.rb:123:in `instrument'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_controller/metal/instrumentation.rb:29:in `process_action'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_controller/metal/params_wrapper.rb:207:in `process_action'
  vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.17/lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/abstract_controller/base.rb:121:in `process'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/abstract_controller/rendering.rb:45:in `process'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_controller/metal.rb:203:in `dispatch'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_controller/metal.rb:246:in `block in action'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/routing/route_set.rb:73:in `call'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/routing/route_set.rb:73:in `dispatch'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/routing/route_set.rb:36:in `call'
  vendor/bundle/ruby/1.9.1/gems/journey-1.0.4/lib/journey/router.rb:68:in `block in call'
  vendor/bundle/ruby/1.9.1/gems/journey-1.0.4/lib/journey/router.rb:56:in `each'
  vendor/bundle/ruby/1.9.1/gems/journey-1.0.4/lib/journey/router.rb:56:in `call'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/routing/route_set.rb:608:in `call'
  vendor/bundle/ruby/1.9.1/gems/rack-openid-1.3.1/lib/rack/openid.rb:98:in `call'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
  vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/etag.rb:23:in `call'
  vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/conditionalget.rb:25:in `call'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/middleware/head.rb:14:in `call'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/middleware/params_parser.rb:21:in `call'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/middleware/flash.rb:242:in `call'
  vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/session/abstract/id.rb:210:in `context'
  vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/session/abstract/id.rb:205:in `call'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/middleware/cookies.rb:341:in `call'
  vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.17/lib/active_record/query_cache.rb:64:in `call'
  vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.17/lib/active_record/connection_adapters/abstract/connection_pool.rb:479:in `call'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
  vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.17/lib/active_support/callbacks.rb:405:in `_run__671942146__call__942014896__callbacks'
  vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.17/lib/active_support/callbacks.rb:405:in `__run_callback'
  vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.17/lib/active_support/callbacks.rb:385:in `_run_call_callbacks'
  vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.17/lib/active_support/callbacks.rb:81:in `run_callbacks'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/middleware/remote_ip.rb:31:in `call'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
  vendor/bundle/ruby/1.9.1/gems/railties-3.2.17/lib/rails/rack/logger.rb:32:in `call_app'
  vendor/bundle/ruby/1.9.1/gems/railties-3.2.17/lib/rails/rack/logger.rb:16:in `block in call'
  vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.17/lib/active_support/tagged_logging.rb:22:in `tagged'
  vendor/bundle/ruby/1.9.1/gems/railties-3.2.17/lib/rails/rack/logger.rb:16:in `call'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/middleware/request_id.rb:22:in `call'
  vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/methodoverride.rb:21:in `call'
  vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/runtime.rb:17:in `call'
  vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.17/lib/active_support/cache/strategy/local_cache.rb:72:in `call'
  vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/lock.rb:15:in `call'
  vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.17/lib/action_dispatch/middleware/static.rb:63:in `call'
  vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:136:in `forward'
  vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:245:in `fetch'
  vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:185:in `lookup'
  vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:66:in `call!'
  vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:51:in `call'
  vendor/bundle/ruby/1.9.1/gems/railties-3.2.17/lib/rails/engine.rb:484:in `call'
 vendor/bundle/ruby/1.9.1/gems/railties-3.2.17/lib/rails/application.rb:231:in `call'
  vendor/bundle/ruby/1.9.1/gems/railties-3.2.17/lib/rails/railtie/configurable.rb:30:in `method_missing'
  vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/urlmap.rb:64:in `block in call'
  vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/urlmap.rb:49:in `each'
  vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/urlmap.rb:49:in `call'
  vendor/bundle/ruby/1.9.1/gems/thin-1.3.1-x86-mingw32/lib/thin/connection.rb:80:in `block in pre_process'
  vendor/bundle/ruby/1.9.1/gems/thin-1.3.1-x86-mingw32/lib/thin/connection.rb:78:in `catch'
  vendor/bundle/ruby/1.9.1/gems/thin-1.3.1-x86-mingw32/lib/thin/connection.rb:78:in `pre_process'
  vendor/bundle/ruby/1.9.1/gems/thin-1.3.1-x86-mingw32/lib/thin/connection.rb:53:in `process'
  vendor/bundle/ruby/1.9.1/gems/thin-1.3.1-x86-mingw32/lib/thin/connection.rb:38:in `receive_data'
  vendor/bundle/ruby/1.9.1/gems/eventmachine-1.0.3-x86-mingw32/lib/eventmachine.rb:187:in `run_machine'
  vendor/bundle/ruby/1.9.1/gems/eventmachine-1.0.3-x86-mingw32/lib/eventmachine.rb:187:in `run'
  vendor/bundle/ruby/1.9.1/gems/thin-1.3.1-x86-mingw32/lib/thin/backends/base.rb:61:in `start'
  vendor/bundle/ruby/1.9.1/gems/thin-1.3.1-x86-mingw32/lib/thin/server.rb:159:in `start'
  vendor/bundle/ruby/1.9.1/gems/thin-1.3.1-x86-mingw32/lib/thin/controllers/controller.rb:86:in `start'
  vendor/bundle/ruby/1.9.1/gems/thin-1.3.1-x86-mingw32/lib/thin/runner.rb:185:in `run_command'
  vendor/bundle/ruby/1.9.1/gems/thin-1.3.1-x86-mingw32/lib/thin/runner.rb:151:in `run!'
  vendor/bundle/ruby/1.9.1/gems/thin-1.3.1-x86-mingw32/bin/thin:6:in `<top (required)>'
  bin/thin:16:in `load'
  bin/thin:16:in `<main>'
maxrossello commented 10 years ago

Hi, looks like you have a Version in database with null name (???). This should be forbidden by database integrity rules.

Can you please tell what database are you using and your system (Windows, Mac, Linux...)? What version of the plugin?

maxrossello commented 10 years ago

Hmmm... no sorry, my mistake

Do you just have an order and no shared versions from projects? Would you try to create a Version in some project and share it globally to see if this helps?

danielwagn3r commented 10 years ago

we've checked that there is now version with NULL as name but we do have versions which are shared with all projects.

maxrossello commented 10 years ago

does changing the NULL in database solve the problem? What Version is it? Is it the newly created order?

danielwagn3r commented 10 years ago

Sorry for the misunderstanding, but I meant no versions with NULL as name.

maxrossello commented 10 years ago

I suspect it could be a bug in your ruby, which I see is 1.9.1 (rather old). Can you please try to cd to your redmine installation, run 'rails console' and try to give the following command:

[].uniq.sort_by{ |v| v.name.downcase}

in the meanwhile, I am installing it myself to try as well

maxrossello commented 10 years ago

Ok, I got a closer hint. Can you please look into your db for column order_id into table ts_permissions and verify if there is any order_id that does not match with any id in table versions?

danielwagn3r commented 10 years ago

I found only one record in ts_permissions where ts_permissions.order_id and any versions.id match, but there are about 10 records in ts_permissions with order_id that do not match any version.id.

Regarding the Ruby version. I use the current Bitnami Redmine Stack, where everything is bundled and preconfigured.

maxrossello commented 10 years ago

Right. Ruby is actually not the problem, rather the mismatch creates nil's in the query that therefore returns error.

Did you remove Versions directly from database? If not, what type of database are you using?

As a protection you may want to edit line 252 and change

{ |v| v.name.downcase}

to

{ |v| v.name.downcase unless v.nil?}

but I'd like to understand the root cause for this problem.

danielwagn3r commented 10 years ago

Just for simplicity here the complete version information:

Environment:
  Redmine version                2.5.1.stable
  Ruby version                   1.9.3-p231 (2012-05-25) [i386-mingw32]
  Rails version                  3.2.17
  Environment                    production
  Database adapter               Mysql2
SCM:
  Subversion                     1.8.5
  Git                            1.9.0
  Filesystem                     
Redmine plugins:
  redmine_app__space             1.0.3
  redmine_app_timesheets         1.3.19
  redmine_watcher_groups         1.0.1
  redmine_wiki_lists             0.0.3
maxrossello commented 10 years ago

Ok, thanks. Now I wish to understand if database mismatch among ts_permissions and versions was due to manual handling or caused by the application. If it was manual, then just remove the mismatched entries in ts_permissions as well, otherwise I need to find the root cause in the application.

danielwagn3r commented 10 years ago

Oh, that's hard to answer, because I'm not the only one working with our Redmine environment. I'm sure we deleted an order but potentially deletion of versions (e.g. via Roadmap) has happened, too.

Btw, the { |v| v.name.downcase unless v.nil?} didn't change anything.

maxrossello commented 10 years ago

You probably still have an error 500, but in another place, having those nil's in the way.

Ok, I replicated the problem.

The problem is that removing some version in the backing project (where versions become orders) leaves stale entries in ts_permissions. This is a bug.

I need to hook up version removal and clean ts_permissions.

In the meanwhile, you can restore your site removing unmatched ts_permissions entries manually.

Thank you

danielwagn3r commented 10 years ago

I didn't delete the version in roadmap in the backing project, but in a normal project.

Is there a way to make a cleanup of all redmine_app_timeseries data, just to begin from a sane point with further testing?

maxrossello commented 10 years ago

There is some irreversible migration, but since you want to wipe out everything and restore a clean environment, you can migrate db back and forth this way:

  1. edit plugins/redmine_app_timesheets/db/migrate/011_ts_remove_issues.rb and comment out the down method
  2. run 'rake redmine:plugins:migrate NAME=redmine_app_timesheets RAILS_ENV=production VERSION=0'
  3. run 'rake redmine:plugins:migrate NAME=redmine_app_timesheets RAILS_ENV=production'
  4. possibly restore edited file

Please dump your database before you do

danielwagn3r commented 10 years ago

Hi, today I discussed with a colleague what he exactly did during his tests and it turned out that he deleted versions from the backing project as he found no other way to delete an order.

I took a quick look at the database scheme and should it be sufficient to repair the database with these deletes?

delete from ts_activities
where order_id not in (select id from versions);

delete from ts_permissions
where order_id not in (select id from versions);

delete from time_entries
where order_id not in (select id from versions);
maxrossello commented 10 years ago

Hi, For what concerns time_entries it is necessary to keep the entries where order_id is null, which are standard redmine time entries not related to order's time sheets

Daniel Wagner notifications@github.com ha scritto:

Hi, today I discussed with a colleague what he exactly did during his tests and it turned out that he deleted versions from the backing project as he found no other way to delete an order.

I took a quick look at the database scheme and should it be sufficient to repair the database with these deletes?

delete from ts_activities where order_id not in (select id from versions); delete from ts_permissions where order_id not in (select id from versions); delete from time_entries where order_id not in (select id from versions);

— Reply to this email directly or view it on GitHub.

danielwagn3r commented 10 years ago

Hi, after

delete from ts_activities
where order_id not in (select id from versions);

delete from ts_permissions
where order_id not in (select id from versions);

the timesheet view opens again. How can we delete an order in a safe way, through the gui? Disable it first and then delete the according version?

maxrossello commented 10 years ago

I have marked this as a bug to be resolved. I need to hook and perform your same actions at order delete in the backing project.

In the meanwhile, you still have to do these manual cleaning actions: order delete was actually not foreseen (it makes sense to delete an order only if it was created wrong, otherwise you can just disable it) and is not supported yet.

Daniel Wagner notifications@github.com ha scritto:

Hi, after

delete from ts_activities where order_id not in (select id from versions); delete from ts_permissions where order_id not in (select id from versions);

the timesheet view opens again. How can we delete an order in a safe way, through the gui? Disable it first and then delete the according version?

— Reply to this email directly or view it on GitHub.

maxrossello commented 10 years ago

When Versions are deleted, related time entries (those with matching order_id, not those with NULL order_id which are related to project or issue) are destroyed automatically