I am using laravel's replicate() method of a Model to generate a copy of exiting instance. It works fine if there are no columns that are to be unique
In my case there are some columns that are to be unique so I use this
$pr = Products::find(\Input::get('id'))->replicate();
$pr['product_code'] = $pr->product_code . '_'.$pr['id'];
$pr['name'] = $pr->name . '_'.$pr['id'];
$pr->save();
This will make sure that if a product is replicated once it will handle the unique column problem. But if the product is replicated again it will cause the problem again.
How I can I solve this issue
I would set in database product_code and name as nullables and then do something like this:
$product = Products::find(\Input::get('id'));
$newProduct = $product->replicate(['product_code', 'name']);
$newProduct->save();
$newProduct->product_code = $product->product_code.'_'.$newProduct->id;
$newProduct->name = $product->name.'_'.$newProduct->id;
$newProduct->save();
Of course you could wrap this into a function in case you do it in multiple places.
Recently ran into this issue, most efficient and effective was just to use unix time stamp. Here is another example to give you a better idea of what is going on without having to null fields and such.
$page = Page::find($id);
$duplicatePage = $page->replicate();
$duplicatePage->name = 'Copy of ' . $page->name;
$duplicatePage->slug = $page->slug . '-' . time();
$duplicatePage->save();
following #Marcin NabiaĆek's answer I solved the issue with small enhancements
$product = Products::find(\Input::get('id'));
$newProduct = $product->replicate();
$newProduct->save();
$newProduct->product_code = str_replace("_".$product->id,"",$product->product_code).'_'.$newProduct->id;
$newProduct->name = str_replace("_".$product->id,"",$product->name).'_'.$newProduct->id;
$newProduct->save();
This will remove the old _id from the name and product code for an entry which already has _id at the end and then add the new _id.
Related
I have found out how to make a page for WordPress, where I can write PHP code into.
However, I can not figure out how to retrieve content from another database.
I have found the connect code:
$wpdb2 = new wpdb($dbname, $dbpass, $dbuname, $dbhost);
but I cannot figure out how to retrieve content from the database.
Can someone give an example?
If, for example, have this query
SELECT number
FROM qr_statistic
WHERE date = '$today'
please see this:
wpdb::get_results( string $query = null, string $output = OBJECT )
now you can write your query:
$result = $wpdb->get_results("SELECT number FROM $wpdb->qr_statistic WHERE WHERE date = '$today'");
also see this link
I currently found out that you can hydrate an Raw sql query.
I have following query:
DB::table(DB::raw('(SELECT *, Y(location) AS longitude, X(location) AS latitude FROM meetings WHERE MBRCONTAINS(#quadrat, location)) AS sub'))
->select(DB::raw('(FLOOR(SQRT(POW((#ibk_breite - sub.latitude) * 111, 2) + POW((#ibk_laenge - sub.longitude) * 111 * ABS(COS(RADIANS(#ibk_breite))),2)))) AS distance, sub.*, latitude, longitude'));
which I hydrate as following
$meetings = Meeting::fromQuery($query->toSql());
In the blade view i need to get some additional data from different tables, for example:
$meeting->user
which references to the User Model. But if I'm not complety wrong that would result to a n+1 problem in a for each loop, because I'm not eager loading it?! So is it possible to eager load the required models as you would normally do with
->with('user', 'books', 'etc...')
??
Also is it possible to paginate it like $meetings = $query->paginate(5); and do $meetings->withPath('home');
EDIT:
Found a solution:
// Do your query stuff
// Get count before the query because it won't work with skip and take parameter
$count = $query->count();
$query->skip($skip);
$query->take($meetingsPerPage);
$meetings = Meeting::fromQuery($query->toSql());
$meetings->load('user', 'interest.image', 'img_thumbnail');
$meetings = new LengthAwarePaginator($meetings, $count, $meetingsPerPage);
$meetings->load acts as ->with().
As last step you need to create a paginator. IMPORTANT: Use query->count() before you set skip() and/or take() Otherwise it will not work.
Original answer from laracasts. Theres also another possibily stated that didn't work for me.
You can use setCollection() function with LengthAwarePaginator object (found in Illuminate/Pagination/AbstractPaginator.php). Use load() for eager loading.
$users = DB::table('users')->paginate();
$users->setCollection(User::hydrate($users->items())->load(['category']));
My solution:
// Do your query stuff
// Get count before the query because it won't work with skip and take parameter
$count = $query->count();
$query->skip($skip);
$query->take($meetingsPerPage);
$meetings = Meeting::fromQuery($query->toSql());
$meetings->load('user', 'interest.image', 'img_thumbnail');
$meetings = new LengthAwarePaginator($meetings, $count, $meetingsPerPage);
$meetings->load acts as ->with(). As last step you need to create a paginator. IMPORTANT: Use query->count() before you set skip() and/or take() Otherwise it will not work.
Original answer from laracasts. Theres also another possibily stated that didn't work for me.
I'm trying to allow admins to create new columns in a sql table from a form that has a fields for the column title, column type and target table. I'm sure I'm not doing this in the most elegant way possible but I'm trying to use the framework rather than have everyone beat me up for directly querying the database. I've created the following controller that almost completely works, however, when I try to use $new_column rather a hard coded string I get an undefined variable exception.
//Capture variables from view
$type = Input::get('type');
$table_name = Input::get('table');
$proposed_name = Input::get('name');
//Convert proposed name into useable column name
$new_column = strtolower(str_replace(' ', '_', (preg_replace('/[^a-zA-Z0-9_ -%][().][\/]/s', '', $proposed_name))));
if($type == 'string')
{Schema::table($table_name, function($table){$table->string($new_column);});}
elseif($type == 'date')
{Schema::table($table_name, function($table){$table->date($new_column);});}
...
//Flash Success
$message = 'Variable "' . $proposed_name . '"" has been successfully created.';
Session::flash('flash_success', $message);
return Redirect::action('VariableManagerController#getIndex');
Is there a way to make this work through the Larval framework or should I just do a raw query to the database?
For the record this will be utilizing a try catch block but that would only further confuse the code above.
$alldata=Input::all();
$table_name = Input::get('table');
Schema::table($table_name, function($table) use ($alldata)
{
$colname=$alldata['name'];
$coltype=$alldata['type'];
$table->$coltype($colname);});
}
I'm trying to match md5(ID) to an id.
SELECT *
FROM `user` u
WHERE
MD5(`user_id`) = '66f041e16a60928b05a7e228a89c3799'
this is ID = 58
I tried something like this. I know I'm close I just don't know what I'm missing
$criteria = new Criteria();
$criteria->addAnd('md5('.User::USER_ID.')', $_REQUEST['fs'], Criteria::CUSTOM);
$user = UserPeer::doSelectOne($criteria);
Any ideas?
First of all, directly using Criteria objects is deprecated not recommended. You should use Active Query classes.
Using these classes, you will be able to write stuff like this :
UserQuery::create()
->where('md5(User.Password) = ?', $_REQUEST['fs'], PDO::PARAM_STR)
->findOne();
You'll notice that I use the PhpName both of the table and the column in the query.
EDIT : For raw conditions, the parameter type has to be specified. You'll find more information on this issue.
After lenghty T&E process I managed to get it done like this
$c = new Criteria();
$c->add(UserPeer::USER_ID, "md5(user.user_id) = \"".$_REQUEST['fs']."\"", Criteria::CUSTOM); // risk of SQL injection!!
$saved_search = UserPeer::doSelectOne($c);
For some reason PropelORM though that $_REQUEST['fs'] was name of the table rather than the value. \"" solved the problem.
So I use the PDO for a DB connection like this:
$this->dsn[$key] = array('mysql:host=' . $creds['SRVR'] . ';dbname=' . $db, $creds['USER'], $creds['PWD']);
$this->db[$key] = new PDO($this->dsn[$key]);
Using PDO I can then execute a MySQL SELECT using something like this:
$sql = "SELECT * FROM table WHERE id = ?";
$st = $db->prepare($sql);
$st->execute($id);
$result = $st->fetchAll();
The $result variable will then return an array of arrays where each row is given a incremental key - the first row having the array key 0. And then that data will have an array the DB data like this:
$result (array(2)
[0]=>[0=>1, "id"=>1, 1=>"stuff", "field1"=>"stuff", 2=>"more stuff", "field2"=>"more stuff" ...],
[1]=>[0=>2, "id"=>2, 1=>"yet more stuff", "field1"=>"yet more stuff", 2=>"even more stuff", "field2"=>"even more stuff"]);
In this example the DB table's field names would be id, field1 and field2. And the result allows you to spin through the array of data rows and then access the data using either a index (0, 1, 2) or the field name ("id", "field1", "field2"). Most of the time I prefer to access the data via the field names but access via both means is useful.
So I'm learning the ruby-mysql gem right now and I can retrieve the data from the DB. However, I cannot get the field names. I could probably extract it from the SQL statement given but that requires a fair bit of coding for error trapping and only works so long as I'm not using SELECT * FROM ... as my SELECT statement.
So I'm using a table full of State names and their abbreviations for my testing. When I use "SELECT State, Abbr FROM states" with the following code
st = #db.prepare(sql)
if empty(where)
st.execute()
else
st.execute(where)
end
rows = []
while row = st.fetch do
rows << row
end
st.close
return rows
I get a result like this:
[["Alabama", "AL"], ["Alaska", "AK"], ...]
And I'm wanting a result like this:
[[0=>"Alabama", "State"=>"Alabama", 1=>"AL", "Abbr"=>"AL"], ...]
I'm guessing I don't have the way inspect would display it quite right but I'm hoping you get the idea by now.
Anyway to do this? I've seen some reference to doing this type of thing but it appears to require the DBI module. I guess that isn't the end of the world but is that the only way? Or can I do it with ruby-mysql alone?
I've been digging into all the methods I can find without success. Hopefully you guys can help.
Thanks
Gabe
You can do this yourself without too much effort:
expanded_rows = rows.map do |r|
{ 0 => r[0], 'State' => r[0], 1 => r[1], 'Abbr' => r[1] }
end
Or a more general approach that you could wrap up in a method:
columns = ['State', 'Abbr']
expanded_rows = rows.map do |r|
0.upto(names.length - 1).each_with_object({}) do |i, h|
h[names[i]] = h[i] = r[i]
end
end
So you could collect up the rows as you are now and then pump that array of arrays through something like what's above and you should get the sort of data structure you're looking for out the other side.
There are other methods on the row you get from st.fetch as well:
http://rubydoc.info/gems/mysql/2.8.1/Mysql/Result
But you'll have to experiment a little to see what exactly they return as the documentation is, um, a little thin.
You should be able to get the column names out of row or st:
http://rubydoc.info/gems/mysql/2.8.1/Mysql/Stmt
but again, you'll have to experiment to figure out the API. Sorry, I don't have anything set up to play around with the MySQL API that you're using so I can't be more specific.
I realize that php programmers are all cowboys who think using a db layer is cheating, but you should really consider activerecord.