Setting a table name in a model? - laravel

Im trying to pass in a table name to my model, as the model operates on two tables, but has the same methods.
I do it like so:
$this->model = new Emotions(array('section' => 'red'));
And in the model I set the table like:
public function __construct($attributes = array(), $exists = false){
parent::__construct($attributes, $exists);
$this->table = $attributes['section'];
}
But I get the error:
Undefined index: section
Any ideas where I'm going wrong?

Yes i get it, This class maybe running twice.
Please try this.
public function __construct($attributes = array(), $exists = false){
parent::__construct($attributes, $exists);
if(isset($attributes['section'])) {
$this->table = $attributes['section'];
}
}
My personal suggestion
<?php
class Emotions extends Eloquent
{
public function setTableName($name)
{
$this->table = $name;
return $this;
}
}
And you can use like this
$emotion = new Emotions(array('foo' => 'bar'))
->setTableName('blabla')
->save();

add below line to your class.
protected $fillable = array('section');
http://laravel.com/docs/eloquent#mass-assignment

Related

Laravel and algolia, ignore array if null

I have this code:
public function toSearchableArray()
{
$data = $this->toArray();
$data['_geoloc'] = $this->_geoloc->toArray();
$data['address'] = $this->address->toArray();
return $data;
}
However sometimes $data['entities'] is null therefore throwing me an error:
[Symfony\Component\Debug\Exception\FatalThrowableError]
Call to a member function toArray() on null
Is there any way to by-pass that?
You need to check elements if they exist and not null before call methods on them, like this:
public function toSearchableArray()
{
$data = $this->toArray();
$data['_geoloc'] = !empty($this->_geoloc) ? $this->_geoloc->toArray() : null;
$data['address'] = !empty($this->address) ? $this->address->toArray() : '';
return $data;
}
Also $this->toArray(); will convert the model instance to an array with all relations. So you need to load them like: $this->load('_geoloc', 'address'); and call only $data = $this->toArray();
I assume address is a relation to another table.
toArray() will convert it, if it was loaded before
public function toSearchableArray()
{
$this->address;
$data = $this->toArray();
return $data;
}
Is _geoloc also a relation to another table?
I think you can try this:
public function toSearchableArray()
{
$data = $this->toArray();
$data['_geoloc'] = $this->_geoloc->toArray();
$data['address'] = $this->address->toArray();
print('<pre style="color:red;">');
print_r($data);
print('</pre>');
exit;
return $data;
}
Hope help for you !!!

Saving Model data to database

I have a Report Model which is like the following.
class Report extends Model
{
protected $table = 'reports';
protected $guarded = [];
public function leadsCollection()
{
return $this->hasMany('App\ReportModels\LeadsCollection');
}
}
A Report can have many LeadsCollection, its Model is the following.
class LeadsCollection extends Model
{
protected $table = 'leadsCollection';
protected $guarded = [];
private $xmlElement;
public function __construct($xmlElement = null, $attributes = array()) {
parent::__construct($attributes);
$this->xmlElement = $xmlElement;
}
public function report()
{
return $this->belongsTo('App\ReportModels\Report');
}
function asArray(){
$reportItem = array();
foreach($this->xmlElement->Leads->Lead as $lead) {
$dateIdentified = date("d/m/Y", strtotime($lead->Date));
$reportItem[] = array(
'LeadID' => (string)$lead->ID,
'Client' => (string)$lead->Client->Name,
'Category' => (string)$lead->Category,
'DateIdentified' => $dateIdentified,
'LeadName' => (string)$lead->Name,
'Owner' => (string)$lead->Owner->Name
);
}
return $reportItem;
}
}
Now I am trying to save some data to a database. So I get a list of all Leads by calling my LeadsCollection and passing it an XML list of Leads.
I then loop these Leads and add it to an array. At the same time however I need to save it to the database. This is what I have so far.
public function getForecastReportForLeads() {
$leads = new LeadsCollection(new \SimpleXMLElement(Helper::getCurrentLeads()));
$reportArray = array();
foreach ($leads->asArray() as $lead) {
$report = new Report();
$report->reportName = 'Lead Forecast';
if($report->save()) {
$leads->leadId = $lead['LeadID'];
$leads->leadCategory = $lead['Category'];
$leads->dateIdentified = $lead['DateIdentified'];
$leads->leadName = $lead['LeadName'];
$leads->owner = $lead['Owner'];
$leads->client = $lead['Client'];
$leads->report_id = $report->id;
$leads->save();
$reportItem = array(
'leadData' => $lead
);
$reportArray[] = $reportItem;
}
}
return $reportArray;
}
So I create the Report item, and within the database if I have 7 Leads I end up with 7 Report rows within my reports table, as it should be. However, when I save the Leads, I only end up with 1 row in my leadsCollection table, every other entry seems to be overridden. I think this is because I am not creating the Lead Object within the loop. However, I cant really create it within the loop because I need to loop whats returned when I first create it.
Not sure how clear I am but is there anything I can add to my Model so I can stop any overriding? Or do I need to do this another way?
Thanks
Either you get the variable inside the save method or initialize the new
$report = new Report($reportItem);
$report->save($report)
I'm having a similar Issue right, let me show my code. It would work for your case. My bug is that I'm updating and the plan_detail.id gets moved instead of creating a new one. But if you create would be fine:
public function store(Request $request)
{
$this->validate($request, [ 'title' => 'required',
'description' => 'required']);
$input = $request->all();
$plan_details = Plan_Detail::ofUser()->get();
$plan = new Plan($request->all());
DB::beginTransaction();
Auth::user()->plans()->save($plan);
try {
foreach ($plan_details as $k => $plan_detail)
Plan::find($plan['id'])->details()->save($plan_detail);
DB::commit();
} catch (Exception $e) {
Log::error("PGSQL plan detail " . $e->message());
DB::rollback();
session()->flash('message', 'Error al guardar el plan de entreno');
}
return redirect('plans');
}

Laravel get relationship model within object after save()

I am using laravel 4.2.
I have two models as below :
class User extends Eloquent{
protected $table = 'users';
public function user_card_details(){
return $this->hasMany('User_card_details');
}
}
And
class User_card_details extends Eloquent {
protected $table = 'user_card_details';
public $timestamps = true;
public $softdeletes = true;
public function user(){
return $this->belongsTo('User')->first();
}
}
And I can save the relationship record using :
$user_card_details = new User_card_details();
$user_card_details->card_number = Input::get('card_number');
$user_card_details->card_exp_month = Input::get('card_expires_m');
$user_card_details->card_exp_year = Input::get('card_expires_y');
$user_card_details->card_cvv = Input::get('card_cvv');
$user->user_card_details()->save($user_card_details);
Up to this it works fine for me.
After save() , I want the user object should be populated with user_details.
So if I want to use the properties, I can use it like :
echo $user->user_card_details->card_number;
But it is not working now.
Any suggestions?
Thanks
You have to remove the () to get the actual model or collection:
echo $user->user_card_details->card_number;
When you're calling the actual function, you'll receive an instance of the Query builder.
Also, it seems that you're not persisting your $user_card_details-object before you try to bind it to your user:
$user_card_details = new User_card_details();
$user_card_details->card_number = Input::get('card_number');
$user_card_details->card_exp_month = Input::get('card_expires_m');
$user_card_details->card_exp_year = Input::get('card_expires_y');
$user_card_details->card_cvv = Input::get('card_cvv');
$user_card_details->save(); //Added this line.
$user->user_card_details()->save($user_card_details);
The more correct way would be:
$user_card_details = [
'card_number' => Input::get( 'card_number' ),
'card_exp_month' => Input::get( 'card_expires_m' ),
'card_exp_year' => Input::get( 'card_expires_y' ),
'card_cvv' => Input::get( 'card_cvv' ),
];
$userCardDetailObj = $user->user_card_details()->create( $user_card_details );
Now, your User_card_detail-instance will be available as the returned object.

Laravel Model - $connection property not working

Why this ain't working?
class Condition extends Eloquent{
protected $connection = 'another-database-connection';
}
But it turns out it connects to the default database.
Any thoughts?
Edit:
The problem is in:
protected function fetchColumns($is = null)
{
if(!empty($this->table)){
$columns = DB::select('DESCRIBE '.$this->getTable());
foreach($columns as $column){
if(!in_array($column, array('id', 'created_at', 'updated_at', 'deleted_at'))){
$this->tableColumns[] = $column->Field;
}
}
}
}
It seems that Laravel mixes databases when trying to get the table columns, that's why I get Table doesn't exist error. The connection is fine.
change:
$columns = DB::select('DESCRIBE '.$this->getTable());
to:
$columns = $this->getConnection()->select('DESCRIBE '.$this->getTable());

Accessing public methods in a Doctrine model (Code Igniter)

I'm trying to add pagination to my code igniter project. I am using Doctrine for my models and I can't seem to use $this->load->model('gif') to access the methods in my controller. I guess a Doctrine model acts differently, but surely there is a way to call the public methods?
Here is my controller:
<?php
class View extends Controller
{
function index()
{
// load pagination class
$gifs = Doctrine::getTable('Gif')->findAll();
$this->load->library('pagination');
$config['base_url'] = base_url().'view/';
$config['total_rows'] = count($gifs);
$config['per_page'] = '5';
$config['full_tag_open'] = '<p>';
$config['full_tag_close'] = '</p>';
$this->pagination->initialize($config);
//load the model and get results
//$this->load->model('gif');
$data['results'] = $gifs->getGifs($config['per_page'],$this->uri->segment(2));
// load the view
$this->load->view('front_images', $data);
}
}
Here is my model
<?php
class Gif extends Doctrine_Record {
public function setTableDefinition()
{
$this->hasColumn('photo_path', 'string', 255, array('unique' => true, 'notnull' => true));
$this->hasColumn('title', 'string', 255, array('notnull' => true));
$this->hasColumn('user_id', 'integer', 4);
$this->hasColumn('token', 'string', 255);
}
public function setUp()
{
$this->actAs('Timestampable');
$this->hasOne('User', array(
'local' => 'user_id',
'foreign' => 'id'
));
}
public function preInsert($event)
{
$this->token = (sha1(rand(11111, 99999)));
}
public function numGifs() {
$result = Doctrine_Query::create()
->select('COUNT(*) as num_gifs')
->from('Gif')
->fetchOne();
return $result['num_gifs'];
}
public function getGifs($offset, $limit)
{
$gifs = Doctrine_Query::create()
->from('Gif g')
->orderBy('g.created_at DESC')
->limit($limit)
->offset($offset)
->execute();
return $gifs;
}
}
How can I call the numGifs and getGifs methods from that controller? Thanks in advance!
I am also using CI in conjunction with doctrine. for reference i am following the tuto located at http://www.phpandstuff.com/articles/codeigniter-doctrine-from-scratch-day-1-install-and-setup .
I don't know if you followed similar steps but using this approach models do not need to be loaded but rather instantiated.
for eg.
$g = new Gif();
$g = $g->getGifs();
(although in this particular case
- $g expects only one row
- Am not sure if we can define getter functions inside the model representing the table itself. in the tuto am following the model contains only the db table definition as well as any relationships)
hope this helps.

Resources