2017-02-27 17 views
0

我有模型自动化,其中有列:数据类型:文本,系列化作为哈希如何发送多种方法如串红宝石

考虑到与散纪录

{ 
1=>"goto 'seznam.cz'", 
2=>"text_field(placeholder: 'jméno').set '[email protected]'", 
3=>"text_field(placeholder: 'heslo').set 'Pass123'", 
4=>"button(xpath: //form[@class='login-form']//button[.='Přejít do Emailu']).click" 
} 

而且我反对浏览器 throught硒的webdriver &我要调用这些散列为序列的方法,是这样的:

automation = Automation.find(params[:automation_id]) 
automation.data.keys.each do |key| 
    browser.send(automation.data[key]) 
end 

但它不”工作因为我试图发送multiplte方法名称作为一个。 首先可以解决为browser.send(:goto,'seznam.cz'),但它并没有帮助我在更大的规模,有没有什么办法解决它,而不尝试创建一些不可能的解析器(for我至少)。

这些方法可以作为

browser.text_field(placeholder: 'jméno').set '[email protected]' 
当然

,但我想以某种方式从散列循环内使自动化它。

任何想法将不胜感激,谢谢!

+0

有明显遗漏了很多的代码因为这似乎需要某种解析才能正常工作。它也看起来像你正在执行可能非常危险的任意代码。 – tadman

+0

你可以使用'eval',但同样,不执行由陌生人 –

+0

提供的代码串的那些只是手动添加到数据库,这样我就可以存储进度,所以这是我的代码,我只是没有找到更好的办法如何存储分步代码。 @maxple EVAL似乎工作,因此,它是好的,如果那是我的代码或是否有更好的方式来做到这一点?不管怎样,谢谢:) –

回答

0

。假定你的意思是:

2=>"text_field(placeholder: 'jméno').set '[email protected]'", 

是要(有效的)电话:

browser.text_field(占位符: 'jméno')集(“有人@ seznam。 cz')

那么你的问题并不像你想像的那么简单,只是把第一个项目称为方法。在这种情况下,第一个“item”是一个实际包含ruby代码的字符串。

这就是为什么maxple建议使用eval,但eval有一些问题。

如果你拥有所有的字符串,那么你可以使用eval,但是如果别人可以编辑这些字符串,那么他们可以执行任意代码。无论如何,我想你都有这个问题。

所以一个选择是简单地使用一个eval循环与“浏览器。#{方法}(#{param})”其中(方法,参数)从字符串中提取。

我们可以首先通过一个简单的例子看起来有点打扫一下:

1=>"goto 'seznam.cz'", 

如果这是真的,你想在每一种情况下做的一切,只是指定的方法和参数,可以那么你可以清理它一点有一个更有趣的数据结构,如:

1 => { method: :goto, args: ['seznam.cz'] } 

然后,你可以这样做:

browser.send(automation.data[key][:method],*automation.data[key][:args]) 
例如,

并允许多个参数。如果您需要将其存储在简单的数据库中,则至少可以为方法和参数指定不同的列,然后将方法字符串转换为方法符号,其中包含to_sym

但这不能帮助您解决更复杂“自动化”就像步骤2那样,因为这里的方法实际上是另一个方法调用另一个参数的结果。

如果你真的需要所有这些存储的而不是简单的Ruby代码在某种自动化的数据库,那么一个选择是把任务分配方法调用,并保存任何间断值你需要。也许是这样的:

object   method   arg 
------   ------   --- 
browser  goto   'seznam.cz' 
browser  text_field  placeholder: 'jméno' 
previous  set   '[email protected]'" 

哪里,如果“对象”是“浏览器”,那么你发送的方法到浏览器,但如果“对象”是“以前”,那么你发送的方法的结果先前的呼叫。

你需要弄清楚如何处理“占位符:‘jméno’”,这是有效地构建一个哈希作为参数,我会留给读者做练习。

也许在这一点上你想知道,如果你真的应该在数据库中存储的Ruby代码。这是一个非常好的问题。 ruby代码通常在ruby文件中更加快乐。 :)


此外,作为另一种普遍的观点,您有:

automation.data.keys.each ... 

但是你已经编号的钥匙,这大概意味着你要叫他们按照一定的顺序。为了确保这一点,你应该使用一个有序集合,如数组,而不是用整数索引的哈希值,否则你可以在最起码的钥匙,即排序:

automation.data.keys.sort.each ... 
+0

(顺便说一句,至于哈希的说法,你也可以(可能)只是把它作为一个(键,值)的阵列 - 另一个理由允许多个参数) –