How do I define sequences in FactoryGirlRails? - ruby-on-rails-3

Previously in Factory girl, we could define sequences like so:
# /spec/factories.rb
FactoryGirl.define do
# this is the sequence in question:
sequence(:random_token) { Digest::MD5.hexdigest(rand.to_s) }
factory :story do
sequence(:title) { |n| "My Cool Story##{n}" }
# Call the sequence here:
token { Factory.next(:random_token) }
description { "#{title} description"}
end
end
Now, when I try that approach - I get a deprecation warning telling me:
WARNING: FactoryGirl::Sequence#next is deprecated.
Use #run instead.
When I replace #next with #run, I get a no-method error.
I can't find the new syntax in any of the docs... Can anyone point me in the right direction?
Thanks

I think you should use Factory.create(...) instead, e.g.
token { Factory.create(:random_token) }

Related

Issue Injecting dataSource into Grails Service

I am running into an issue when trying the following in my Serivce:
class SendingMailService {
def dataSource // the Spring-Bean "dataSource" is auto-injected
def sendXLSMail() {
def db = new Sql(dataSource)
//additional code such as query, execution follows
}
}
When I execute this code I get the error: "Must specify a non-null Connection". From what I have read I believe the code above should work (this is not a Unit Test)...so clearly I am missing something with respect to Grails Services?
Thank you for any help here,
Ok months later I had some time to look into this one.
I tried a couple of things to get the dataSource to autoinject into a service but I kept getting a null connection. Ultimately I landed on passing the datasource from the controller which is not very elegant but at least it works. I hope this helps someone else out as I have seen some similar issues out there. Still would like to know why the autoinject does not work but I think I would have to dig deeper into Grails to understand that.
class MyController {
def dataSource
def someControllerMethod() {
MyService myService = new MyService()
myService.serviceMethodQuery(dataSource)
}
}
//////////////////////
class MyService {
def serviceMethodQuery(Object dataSource){
//use your datasource as you normally would
}
}

Notes attributes syntax changed? - Notes attributes via API call fails for me

Hello Shopfiy Developers!
I'm having an issue with the notes attributes via API call. It used to work up until a month ago and then things start to go sideways. Has any syntax changed? Here is a snippet of my code that returns an error in the for loop.
Error message "Undefined index: note_attribute right at the foreach line"
// Overwrite custom status field if it's defined in note-attributes
if(array_key_exists('note-attributes', $o))
{
// For whatever reason, the note-attributes are formatted
// differently if there's only one key => value pair
// ( * see examples at end of this file )
// If the note-attribute array has the key 'name' in it, it's just a single pair.
// Otherwise, the note-attribute array would be numerically indexed with keys 0,1,2.. etc
if(array_key_exists('name',$o['note-attributes']['note_attribute']))
{
if($o['note-attributes']['note_attribute']['name'] == "custom_status")
$arr_tmp[7] = $o['note-attributes']['note_attribute']['value'] ;
}
else
{
foreach($o['note-attributes']['note_attribute'] as $na) //Fails here
{
if($na['name'] == "custom_status")
$arr_tmp[7] = $na['value'] ;
}
}
}
Your help is much appreciated. Thank you.
The issue here was due to a change in XML node syntax; Shopify had a regression that changed note-attributes to note_attributes in the response and it was changed back.

Defaults in Symfony2 routing not being passed properly

I am currently trying to configure a routing option in Symfony2 so /cms will route to /cms/role/view. However, the passing of defaults doesn't seem to work properly.
/src/MyProject/CMSBundle/Resources/config/routing.yml
MyProjectCMS_specific:
pattern: /cms/{page}/{option}
defaults: { _controller: MyProjectCMSBundle:Main:index, page: role, option: view }
requirements:
_method: GET
/src/MyProject/CMSBundle/Controller/MainController.php
<?php
namespace MyProject\CMSBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class MainController extends Controller
{
public function indexAction($page, $option)
{
$response = null;
/* Switch statement that determines the page to be loaded. */
return $response;
}
}
?>
The problem is that when I try to go to `localhost/app_dev.php/cms', it gives me the following error:
Controller "MyProject\CMSBundle\Controller\MainController::indexAction()" requires that you provide a value for the "$page" argument (because there is no default value or because there is a non optional argument after this one).
500 Internal Server Error - RuntimeException
However, if I try to visit localhost/app_dev.php/cms/role or localhost/app_dev.php/cms/role/view, it gives me the correct page. I've tried adding a default route to /cms, but it still gives me the same error. How is this possible and how can I fix this?
Thanks in advance.
I don't know what is the difference between what you wrote and
public function indexAction($page = "role", $option = "view")
but maybe you could try it and tell us.

Yii model is validating but data could not be saved

I have a yii application. Data is validated properly. the $model->validate() returns true but data is not being saved. Is there any way that I know about the error. It does nothing. neither prints error nor any warning.
if (isset($_POST['Invoice'])) {
$model->validate();
$model->attributes = $_POST['Invoice'];
if (!$model->validate()) {
die(CVarDumper::dump($model->errors,10,true));
}
if ($model->save()) {
die("Data saved");
$this->redirect(array('view', 'id' => $model->id));
} else {
CVarDumper::dump($model->attributes,10,true);
CVarDumper::dump($model->errors,10,true);
}
}
if you override beforeSave or afterFind method in your model,
public function beforeSave() {
return true; //don't forget this
}
public function afterFind() {
return true; //don't forget this
}
make sure you return true for those function
If save() is returning true and there are no errors as such in your database and queries. Only thing, thats possible is you haven't marked some of the column safe for mass assignment via "$model->attributes".
Make sure the column you are trying to save are marked safe in the "rules" function in your model. You can mark columns safe via adding the following rule in "rules" function in the model.
array ( "column_name1, column_name2 ....." , "safe" )
I've just ran into something similar to this. Everything was validating correctly, and $model->save() was returning true, but no data was saved in the database.
The problem and solution was that I was creating the $model object like so:
$model = ClassName::model();
but you need to create the object like so:
$model = new ClassName;
If you have this problem, you replace this:
$model->save(false)
This solves your problem.
If you use $model->save(); the filters is running that is not good for you.
Fire up some logging and see what going on...
I got the same error when I was using reCaptcha. I just did this and it worked:
$model->scenario = NULL;
Make sure you do this AFTER validation.
I had the same issue, my mistake was with the post name in the controller, where I used $model->save. I had given wrong - if(isset($_POST['postname']))
If I am not wrong, you are doing an AR save() in the $model->save() method. You do not get any error, but the data is not saved as well.
If this is the case you would like to do a:
die(CVarDumper::dump($arObj->errors,10,true));
after the $arObj->save(); call. Most of the time this happens because of the Database rejecting the values provided for insert or update.
Also do not override your model constructor:
function __construct() { } // don't do this
The issue for me was that I had a property for the column name in the ActiveRecord class, so it wasn't saving.
You should not declare properties for column names as I guess the magic methods __get() and __set() are used to save data, I guess by checking if there are column changes when you click the save() method to avoid useless SQL queries. In my case, because the column was a user-declared property, it wasn't in the columns list and therefore changes to it were not detected.
Hope this helps other people

IDEA GDSL How to add a method defination to all files(Classes) in a folder?

In my Grails Application, there a folder grails-app/mongoDomain. In this folder there are several classes that too in various packages.
I want to add a GDSL Defination for a method say "save()" to all classes inside the folder grails-app/mongoDomain.
I was successfully able to add this method to a single class, but any method to add in all classes in grails-app/mongoDomain??
.
.
I tried Doing this, but it did't worked..
def mongoDomainContext = context(pathRegexp: /.*grails-app\/mongoDomain.*/)
contributor(mongoDomainContext) {
method(name: 'save', type: 'void', params: [closure: { }])
}
But the above code did't worked, What is the right method for doing it??
.
.
Regards
Kushal
Unfortunately, there's no such GDSL primitive yet. In Griffon, they have the following GDSL fragment using undocumented features:
['Controller', 'Model', 'View', 'Service'].each { type ->
String artifactPath = type.toLowerCase() + 's'
contributor(ctype: PsiJavaPatterns.psiClass().withName(PlatformPatterns.string().matches(/.*${type}/))) {
def path = psiClass.containingFile.originalFile.virtualFile.path
if (path =~ ".*/*griffon-app/${artifactPath}/.*") {
delegatesTo(findClass("griffon.core.Griffon${type}"))
if (type == 'View') {
addNodeContributions(delegate)
}
}
}
}
They match on both class name and its path here, you need only the second part, inside the conributor call.
Here's how I did it and it works. Great thanks to Peter Gromov for providing the hint.
def mongoContext = context(
ctype: PsiJavaPatterns.psiClass().withName(PlatformPatterns.string().matches(/.*/))
)
contributor(mongoContext) {
def path = ""
try {
path = psiClass.containingFile.originalFile.virtualFile.path
} catch (Exception e) {/*This is to prevent any non Class null matches*/}
if (path =~ ".*/*grails-app/mongoDomain/.*")//Matches Directory
{
//Code Here to add methods/Properties etc
}
}
It worked like a charm. Thanks to all.