Bug 1295927 - [RFE] "NoMethodError: undefined method `where' for MiqAeMethodService::MiqAeServiceClassification:Class"
Summary: [RFE] "NoMethodError: undefined method `where' for MiqAeMethodService::MiqAeS...
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: Red Hat CloudForms Management Engine
Classification: Red Hat
Component: Automate
Version: 5.5.0
Hardware: Unspecified
OS: Unspecified
unspecified
medium
Target Milestone: GA
: 5.7.0
Assignee: mkanoor
QA Contact: Matouš Mojžíš
URL:
Whiteboard: automate
Depends On:
Blocks: 1337261 1346951
TreeView+ depends on / blocked
 
Reported: 2016-01-05 19:48 UTC by mkanoor
Modified: 2017-01-12 04:50 UTC (History)
10 users (show)

Fixed In Version:
Doc Type: Enhancement
Doc Text:
There was a request to support Where Method for service models. Starting in Rails 4 "find" has been deprecated in favor of "where when" accessing ActiveRecord. Using where in an Automate method generated the NoMethodError. The required Where Method support has been added with this release.
Clone Of:
: 1337261 1346951 (view as bug list)
Environment:
Last Closed: 2017-01-11 20:02:19 UTC
Category: ---
Cloudforms Team: ---
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
automation.log (2.33 KB, text/plain)
2016-04-26 11:52 UTC, Matouš Mojžíš
no flags Details
automation log last rows (1.10 KB, text/plain)
2016-05-05 14:25 UTC, Matouš Mojžíš
no flags Details
latest automation log (4.96 KB, text/plain)
2016-07-14 13:15 UTC, Matouš Mojžíš
no flags Details

Description mkanoor 2016-01-05 19:48:23 UTC
Description of problem:
Starting in Rails 4 find has been deprecated in favor of where when accessing ActiveRecord. Using where in an Automate method generates the NoMethodError

Version-Release number of selected component (if applicable):
5.5

How reproducible:
100%

Steps to Reproduce:
1. Use an automate method
2. With the following script
tag = $evm.vmdb('classification').where('parent_id = ? AND description = ?',
                                       department_classification.id, 'Systems Engineering']).first
3. The NoMethodError is generated

Actual results:
NoMethodError

Expected results:
The call should succeed

Additional info:

Comment 3 CFME Bot 2016-01-05 23:01:12 UTC
New commit detected on ManageIQ/manageiq/master:
https://github.com/ManageIQ/manageiq/commit/b0474c8a5e1a8738c0421218d1aec6965a8f5a19

commit b0474c8a5e1a8738c0421218d1aec6965a8f5a19
Author:     Madhu Kanoor <mkanoor>
AuthorDate: Tue Jan 5 14:59:46 2016 -0500
Commit:     Madhu Kanoor <mkanoor>
CommitDate: Tue Jan 5 14:59:46 2016 -0500

    Support where method for service models
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1295927
    
    Starting in Rails 4 the where method should be used instead
    of find when accessing ActiveRecord Objects. The Automate
    Service Model wraps the ActiveRecord objects and wasn't exposing
    the class method where.

 lib/miq_automation_engine/engine/miq_ae_service_model_base.rb | 2 +-
 spec/lib/miq_automation_engine/miq_ae_service_model_spec.rb   | 8 ++++++++
 2 files changed, 9 insertions(+), 1 deletion(-)

Comment 4 mkanoor 2016-01-06 17:05:13 UTC
As part of documentation we should mention that from Automate Methods you can't chain the 'where' methods to create a complex query.

e.g this would be invalid in an Automate Method
query = $evm.vmdb(:vm).where(:vendor => "redhat")
query = query.where(:id => vm_id) if vm_id
query.first

This would have to be done as a single where 
if vm_id
  query = $evm.vmdb(:vm).where('vendor = ? AND id = ?', 'redhat', vm_id)
else
  query = $evm.vmdb(:vm).where('vendor = redhat')
end
query.first

Comment 5 Matouš Mojžíš 2016-04-26 11:51:48 UTC
Hello, I would need more information to verify this BZ.I tried to reproduce it.
I have created automation domain and added inside new method with that code.
First I wasn't able to validate it, because "[" was missing.
Was it intended?
It was validated with fixed code:
tag = $evm.vmdb('classification').where('parent_id = ? AND description = ?',
                                       [department_classification.id, 'Systems Engineering']).first
Then I tried to Simulate it. Automate -> Simulate:
System/Process: Automation
Message: create
Request: Name of my method
Type: None
Execute methods: checked
Automate log attached.

Comment 6 Matouš Mojžíš 2016-04-26 11:52:43 UTC
Created attachment 1150887 [details]
automation.log

Comment 7 mkanoor 2016-04-26 13:15:36 UTC
System/Process => Automation          should be Request not Automation

You need to create an instance in your Domain in the System/Request class with the same name as the method.

Step1. Create a new domain called "TESTING"

Step2. Navigate to the ManageIQ domain and copy the System/Request/InspectMe instance to your domain "TESTING"

Step3. Edit the InspectMe instance properties in your domain and change its name to "MyMethod"

Step4. Edit the instance "MyMethod" so that the method points to your method e.g. WhereTest.

Step5. Create a new method in the "MyMethod" class called WhereTest and copy the where script into this Method.

Step6. Automate -> Simulate
       System/Process: Request
       Message: create
       Request: WhereTest
       Type: None
       Execute methods: checked

Hit Submit check logs

Comment 8 Matouš Mojžíš 2016-05-05 14:24:34 UTC
Okay, I tried it in 5.6.0.5-beta2.4.20160503153816_1fb554f.
I wasn't  able to reproduce it with first code, so I have taken second code, which was:
query = $evm.vmdb(:vm).where(:vendor => "redhat")
query = query.where(:id => vm_id) if vm_id
query.first
In 5.5 it gave me that NoMethodError, but in 5.6 it gave me NameError: undefined local variable or method `vm_id' for main:Object.
So I added vm_id variable to make it work:
vm_id = '1234'
query = $evm.vmdb(:vm).where(:vendor => "redhat")
query = query.where(:id => vm_id) if vm_id
query.first
Then NoMethodError appeared.
Error log added as attachment.

Comment 9 Matouš Mojžíš 2016-05-05 14:25:32 UTC
Created attachment 1154233 [details]
automation log last rows

Comment 10 Greg McCullough 2016-05-17 23:27:50 UTC
Ask from bascar to back-port this change to 5.5.z which would enable customers to update/test automation scripts prior to 5.6 update.

Comment 12 CFME Bot 2016-06-14 16:32:30 UTC
New commit detected on cfme/5.5.z:
https://code.engineering.redhat.com/gerrit/gitweb?p=cfme.git;a=commitdiff;h=db5c1392fe738e45a6e274bc3cc34351c578a248

commit db5c1392fe738e45a6e274bc3cc34351c578a248
Author:     Madhu Kanoor <mkanoor>
AuthorDate: Tue Jan 5 14:59:46 2016 -0500
Commit:     Madhu Kanoor <mkanoor>
CommitDate: Tue Jun 14 11:02:32 2016 -0400

    Support where method for service models
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1295927
    
    Starting in Rails 4 the where method should be used instead
    of find when accessing ActiveRecord Objects. The Automate
    Service Model wraps the ActiveRecord objects and wasn't exposing
    the class method where.

 lib/miq_automation_engine/engine/miq_ae_service_model_base.rb | 2 +-
 spec/lib/miq_automation_engine/miq_ae_service_model_spec.rb   | 8 ++++++++
 2 files changed, 9 insertions(+), 1 deletion(-)

Comment 15 mkanoor 2016-07-08 18:45:35 UTC
Hi Matous,
Can you attach your script and the corresponding log.
The vm_id local attribute that you have should point to a valid vm id in the database.
Thanks,
Madhu

Comment 16 Matouš Mojžíš 2016-07-11 09:39:00 UTC
I actually can't reproduce it now on 5.5.5, because enabling created domains is broken. I can try it when that issue is fixed.

Comment 17 Matouš Mojžíš 2016-07-14 13:15:50 UTC
Created attachment 1179854 [details]
latest automation log

Comment 18 Matouš Mojžíš 2016-07-14 13:17:00 UTC
Ahhh, this is 5.6 version of that BZ, so:

Code:
vm_id = '1234'
query = $evm.vmdb(:vm).where(:vendor => "redhat")
query = query.where(:id => vm_id) if vm_id
query.first

Error is in automation.log

Comment 19 mkanoor 2016-07-14 16:08:18 UTC
Hi,
You can't use the query with multiple chained where clauses, it would all have to be in a single where clause.
query = $evm.vmdb(:vm).where('vendor = ? AND vm_id = ?', ['vmware', vm_id])
query.first


These calls are running via DRb and are not direct RAILS calls.
DRb works like a client/server and the data has been returned from the server after the first where call, that result is an array. The Automate Method is the client and the Automate engine is the server.

Thanks,
Madhu

Comment 20 Matouš Mojžíš 2016-07-19 09:58:01 UTC
Hi, it works.
So I can make it verified? It's still on dev.

Comment 21 Matouš Mojžíš 2016-07-19 15:27:14 UTC
Verified in 5.6.0.13. Simulation worked without an error.


Note You need to log in before you can comment on or make changes to this bug.