Jono B Sat Jan 08 11:20:50 -0500 2011

Subject: Associate array insert/update saving

Hi,

Is it possible to send an associate array to the ->save() function, that automatically maps array keys to table columns?

I've just throw something together quickly, along the following lines.

 1 //get all the columns for this table
 2 $pull_cols = mysql_query("SHOW COLUMNS FROM " . clean_string($table)) or die("MYSQL error: " . mysql_error());
 3 
 4 // Put the columns names into a non-associative array
 5 while ($columns = mysql_fetch_assoc($pull_cols))
 6 {
 7     $sql_columns[] = $columns["Field"];
 8 }
 9 
10 foreach ($_POST as $key => $value)
11 {
12     // Check to see if the variables match up with the column names
13     if (in_array($key, $sql_columns) && trim($value))
14     {
15         $sql_value_use[] = $this->sanitise_value($value);
16     }
17 
18     $this->sql_statement = " 
19                 INSERT INTO " . $table . "(" . implode(", ", $sql_columns_use) . ")
20                 VALUES (" . implode(",", $sql_value_use) . ")";
21    //etc
22    //etc
23 }

I realise that I could do this manually for each upate/insert query, but just wondering if there is already some in built magic or plans to handle this?


Benjamin P Sun Jan 09 14:44:14 -0500 2011

It's called update_attributes:
http://www.phpactiverecord.org/docs/ActiveRecord/Model#methodupdate_attributes

$model = new Model;
$model->update_attributes($_POST); // implicit save()
Jono B Tue Jan 11 15:32:07 -0500 2011

Hi Ben,

Thanks for the reply. That is very very close to what I was looking for.

One drawback, however, is that the Model tries to update all items in the array, whether they are present in the underlying table or not. Ideally, the Model should only update the values for each item if there is a corresponding table column for each item.

Kien La Tue Jan 11 17:01:21 -0500 2011

This can work if you explicitly specify what fields you want to allow to be mass updated using $attr_accessible which is good practice to follow anyway.

http://www.phpactiverecord.org/docs/ActiveRecord/Model#var$attr_accessible

I can see doing as you suggest being a lot simpler so I need to think of the trade offs of allowing that.

Alternatively, you could use set_attributes_via_mass_assignment directly and pass false to the $guard_attributes param:

$model->set_attributes_via_mass_assignment($_POST,false);
$model->save();

Jono B Wed Jan 12 08:18:20 -0500 2011

Although a bit long winded, using $attr_accessible worked perfectly.

Thanks Kien.

(1-4/4)