Bug 1295927 - [RFE] "NoMethodError: undefined method `where' for MiqAeMethodService::MiqAeServiceClassification:Class"
[RFE] "NoMethodError: undefined method `where' for MiqAeMethodService::MiqAeS...
Status: CLOSED CURRENTRELEASE
Product: Red Hat CloudForms Management Engine
Classification: Red Hat
Component: Automate (Show other bugs)
5.5.0
Unspecified Unspecified
unspecified Severity medium
: GA
: 5.7.0
Assigned To: mkanoor
Matouš Mojžíš
automate
: FutureFeature, TestOnly, ZStream
Depends On:
Blocks: 1337261 1346951
  Show dependency treegraph
 
Reported: 2016-01-05 14:48 EST by mkanoor
Modified: 2017-01-11 23:50 EST (History)
10 users (show)

See Also:
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.
Story Points: ---
Clone Of:
: 1337261 1346951 (view as bug list)
Environment:
Last Closed: 2017-01-11 15:02:19 EST
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


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

  None (edit)
Description mkanoor 2016-01-05 14:48:23 EST
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 18:01:12 EST
New commit detected on ManageIQ/manageiq/master:
https://github.com/ManageIQ/manageiq/commit/b0474c8a5e1a8738c0421218d1aec6965a8f5a19

commit b0474c8a5e1a8738c0421218d1aec6965a8f5a19
Author:     Madhu Kanoor <mkanoor@redhat.com>
AuthorDate: Tue Jan 5 14:59:46 2016 -0500
Commit:     Madhu Kanoor <mkanoor@redhat.com>
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 12:05:13 EST
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 07:51:48 EDT
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 07:52 EDT
Created attachment 1150887 [details]
automation.log
Comment 7 mkanoor 2016-04-26 09:15:36 EDT
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 10:24:34 EDT
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 10:25 EDT
Created attachment 1154233 [details]
automation log last rows
Comment 10 Greg McCullough 2016-05-17 19:27:50 EDT
Ask from bascar@redhat.com 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 12:32:30 EDT
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@redhat.com>
AuthorDate: Tue Jan 5 14:59:46 2016 -0500
Commit:     Madhu Kanoor <mkanoor@redhat.com>
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 14:45:35 EDT
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 05:39:00 EDT
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 09:15 EDT
Created attachment 1179854 [details]
latest automation log
Comment 18 Matouš Mojžíš 2016-07-14 09:17:00 EDT
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 12:08:18 EDT
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 05:58:01 EDT
Hi, it works.
So I can make it verified? It's still on dev.
Comment 21 Matouš Mojžíš 2016-07-19 11:27:14 EDT
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.