Datamapper Clone Record w/ New ID - database

class Item
include DataMapper::Resource
property :id, Serial
property :title, String
end
item = Item.new(:title => 'Title 1') # :id => 1
item.save
item_clone = Item.first(:id => 1).clone
item_clone.save
# => <Item #id=1 #title="Title 1" ...
This does "clone" the object as described but how can this be done so it applies a different ID once the record is saved, e.g.
# => <Item #id=2 #title="Title 1" ...

clone is going to give you an object copy, which isn't really what you want - you want to just duplicate the record in the db, correct? The way I have done this with DM in the past is like so:
new_attributes = item.attributes
new_attributes.delete(:id)
Item.create(new_attributes)
You can also do it in one line:
Item.create(item.attributes.merge(:id => nil))

Related

Get specific columns on an Included Entity: Invalid inside an 'Include' operation, since it does not represent a property access: 't => t.MyProperty'

One of my linked tables PropertyInfo has an image column, which I don't want to retrieve, every time I .Include() that table. Therefore I took the following approach:
user = _context.Users.Where(x => x.Id == idOfUser)
.Include(x => x.Co.PropertyInfo.Select(i =>
new PropertyModel(
Id = i.Id,
Date = i.Date,
CompanyNumber = i.CompanyNumber,
LinkedCategories = i.LinkedCategories,
LinkedReviews = i.LinkedReviews)))
.ThenInclude(x => x.LinkedCategories)
.ThenInclude(x => x.LinkedReviews)))
.Take(1)
.FirstOrDefault()
This code throws an error:
The expression [EXPRESSION I PASTED ABOVE] is invalid inside an 'Include' operation, since it does not represent a property access: 't => t.MyProperty'....
Is it possible that I'm trying to assign the linked Tables like LinkedCategories and LinkedReviews which are being ThenInclud-ed? Or is this related to something else? How can I include entities without querying for all of the columns?
Maybe something like this if you have an empty constructor in PropertyModel.
You definitely can make it with single query. I don't know what is the structure of your models. For more accurate answer, you can share them.
user = _context.Users.Where(x => x.Id == idOfUser)
.Select(i => new PropertyModel
{
Id = i.PropertyInfo.Id,
Date = i.PropertyInfo.Date,
CompanyNumber = i.PropertyInfo.CompanyNumber,
LinkedCategories = i.PropertyInfo.LinkedCategories,
LinkedReviews = i.PropertyInfo.LinkedReviews
})
.Take(1)
.FirstOrDefault()

Add value to new collection

I have created a new collection, when I try to add new values with a key in a foreach loop its not working. It only appends the 1st value. I want it to add all.
Here my code:
$new = new Collection();
foreach($messages as $message){
$new['message'] = $message->message;
}
But in the end instead of returning all messages, it only returns the 1st message:
{"message":"first"}
Instead it should have returned
{"message": "first", "message": "second"}
What is the problem?
Also when I do it without giving a key to a collection, it returns all:
foreach($messages as $message){
$new = $message->message;
}
You have an array with the same key, so the for loop overrides the same value again and again.
If you want a collection that contains objects with the same key you can change the following code to your need:
$new = array();
foreach ([1, 2, 3] as $i) {
$new[] = array('message' => $i);
}
$collection = collect($new);
Your making a collection with 1 key: namely "message" and then proceed to overwrite this key for the duration of your loop. PHP thus handles this as shown in your question: a collection with 1 key and 1 value.
This makes perfect sense (for example, how many houses are on your home address? Only one right? What would happen to your mail if there were 16 houses with the exact same address?).
What you want simply isn't possible: how should PHP know what it should return when you ask for the value at "message" if the entire data structure would consist out of the same key?
test this code :
$messages=['ali','reza','sara'];
$new = new Collection();
foreach($messages as $key=>$message){
$new->prepend($message,$key);
}
dd($new);
output :
Collection {#475 ▼
#items: array:3 [▼
2 => "sara"
1 => "reza"
0 => "ali"
]
}

Access an array item that is an anonymous hash in Template Toolkit in Perl

I have this piece of code as part of a foreach loop in my controller:
my $gr = My::Model::Group->new(id => $gra->gr_id);
$gra = My::Model::Group::Admin->new(id => $gra->id);
push(#$groups, {$gr => $gra});
In #$groups array I want to store anonymous hashes where the key element is the group object and the value element is the admin of that group object. Then in the template I want to show the list of different groups that the admin can log in, for that I have this code:
[%- FOREACH gr IN groups -%]
<li><input type="radio" name="group" value="[% gr.id %]">[% gr.name %]</input></li>
[%- END -%]
I know that the p IN partners is not right but is to show you what I want to achieve. Any suggestions on the template code?
duskwuff already explains in their answer that you can't use objects as hash keys as they get serialized and you'll lose the object-ness. My answer builds on that.
Let's say you have an array of arrays instead, where each inner array holds a pair of objects. I've created Moo classes to illustrate.
package My::Model::Group;
use Moo;
has [qw/id name/] => ( is => 'ro' );
package My::Model::Group::Admin;
use Moo;
has [qw/id name/] => ( is => 'ro' );
package main;
my $groups = [
[
My::Model::Group->new( id => 1, name => 'group1' ) =>
My::Model::Group::Admin->new( id => 1, name => 'foo' )
],
[
My::Model::Group->new( id => 2, name => 'group2' ) =>
My::Model::Group::Admin->new( id => 1, name => 'foo' )
],
[
My::Model::Group->new( id => 3, name => 'group3' ) =>
My::Model::Group::Admin->new( id => 1, name => 'bar' )
],
[
My::Model::Group->new( id => 4, name => 'group4' ) =>
My::Model::Group::Admin->new( id => 1, name => 'foo' )
],
];
There are four pairs. Two admins, four groups. Three of the groups belong to the foo admin, and one to bar. Now let's look at the template.
use Template;
my $tt = Template->new();
$tt->process( \*DATA, { groups => $groups }, \my $output )
or die $tt->error;
print $output;
__DATA__
[%- FOREACH item IN groups -%]
[%- DEFAULT by_admin.${item.1.name} = [] -%]
[%- by_admin.${item.1.name}.push(item.0) -%]
[%- END -%]
[%- FOREACH admin IN by_admin.keys.sort -%]
[%- FOREACH group IN by_admin.$admin -%]
[%- admin %] -> [% group.id %]
[%- END -%]
[%- END -%]
The relevant part obviously is the DATA section. We need to reorganize the array data structure into a hash that has the admins, and then each group sorted into one of the admin slots.
We don't need to create the by_admin variable. It will be created globally implicitly. But we do need to set a default value for $by_admin->{$item[0]->name} (I'm using Perl syntax now, to make it easier to understand). It seems like Template Toolkit does not know autovivification, and the DEFAULT keyword is similar to the //= assignment operator in Perl.
We can then push the first element of item into the array ref we just created (if it didn't exist yet) inside the hash ref element with the key item.1.name inside by_name.
Once we're done preparing, the rest is just a simple loop. We iterate the sorted keys of by_admin, and then iterate the array ref that's behind that key.
Here's the output:
bar -> 3
foo -> 1
foo -> 2
foo -> 4
It would make sense to do the preprocessing not in a template, but in your controller instead. As normal Perl code it should be easier to read.
my %by_admin;
for my $group (#$groups) {
push #{ $by_admin{ $group->[1]{name} } }, $group->[0];
}
Note that I have omitted use strict and use warnings for brevity.
You will need to rework your code significantly to make this possible.
Keys in Perl hashes are strings, not scalars. Using anything that isn't a string as a key in a hash (e.g, $gr in the expression { $gr => $gra } will cause it to be stringified, just as if you had interpolated it into a string or printed it. Unless you have explicitly overloaded the "" operator on the My::Model::Group object, the key will end up being stored as a literal string along the lines of:
"My::Model::Group=HASH(0x1234567890)"
This string cannot be converted back to the original object -- in fact, the original object was probably garbage-collected as soon as it went out of scope, so it no longer exists at all.
Consider storing the pair as an array reference instead, e.g.
push #$groups, [$gr, $gra];

PDO Prepared Statement Execution - How to get only associative keys?

This should be a simple thing to solve...
I have got these estatements when a user logs in:
$query = $conn->prepare("SELECT * FROM admins WHERE username = :user AND password = :pass");
$query->bindValue(":user", $user);
$query->bindValue(":pass", md5($pass));
$query->execute();
Now if the user exists, I return the user information from the database, but if not, I return false instead...
if($query->rowCount() > 0) {
$admininfo = $query->fetchAll(PDO::FETCH_ASSOC);
} else {
return false;
}
But when I var_dump the variable $admininfo I get an array with a number key before the actual array... like this:
array (size=1)
0 => <---- I DONT KNOW WHERE THIS COME FROM. I USED PDO::FETCH_ASSOC
array (size=9)
'id' => string '1' (length=1)
'username' => string 'admin' (length=5)
'password' => string '21232f297a57a5a743894a0e4a801fc3' (length=32)
'permissionid' => string '1' (length=1)
'name' => string 'Administrador' (length=13)
'lastname' => string 'Softing' (length=7)
'phonenumber' => null
'cellphonenumber' => null
'info' => null
I will put this information inside the SESSION array, so I want to access it by $_SESSION["admininfo"]["username"] or $_SESSION["admininfo"]["phonenumber"]
but I have to put something like this instead: $_SESSION["admininfo"][0]["phonenumber"].
How can I remove that 0 from the keys? Thank you!
According to the documentation for fetchAll, it will return an array of elements. This is because it is getting all of the rows in the table that match your criteria. In your case, you are only getting back one row, located at index 0. If you know you only want one result, use fetch instead of fetchAll. It will get rid of the 0.
You're using fetchAll. This will give you an array of DB rows -- of all the rows that were matched.
Use fetch in a while loop to go through individual rows one by one.

Reference smarty array element by value?

Total newbie with smarty; I did try to research before asking but couldn't figure this out. My application provides me with a nested array structure like this:
custom_fields => Array (2)
0 => Array (6)
name => "key-specs"
type => "textarea"
code => "key-specs"
value => "here are some product specifications"
sd => "05/01/2013 - 09:25:44 PM"
titled => ""
1 => Array (6)
name => "key-specs-li-class"
type => "dropdownlist"
code => "key-specs-li-class"
value => "flg4_icon"
sd => "05/01/2013 - 09:25:44 PM"
titled => ""
Instead of looping through the array, I'd really like to simply reference the outer array by the "name" dimension within the inner array. For example, I know that the name "key-specs" exists somewhere in the array, and all I want to do is quickly retrieve the "value" string that resides at the same index.
Any way to do this type of direct referencing, or am I going to have to loop?

Resources