I'm having trouble figuring out how to call a class function, in this case File->saveFile() through the parent class Article
class Article extends Model {
public $table = 'pl_gen_article';
public function background_image () {
return $this->morphOne('App\Ubercms\File', 'fileable');
}
}
class File extends Model {
public $table = 'ubercms_file';
public function saveFile (UploadedFile $file) {}
}
$articleId = \Route::input('id');
$article = Article::findOrFail($articleId);
$file = $request->file('image');
// ----------------------
// Attempts
// 1.
$article->background_image->saveFile($file)
// 2.
$image = new $article->background_image();
$image->saveFile($file);
How do I create a File model instance from Article model?
Through the Laravel Api Docs traced the response of $article->background_image() which as MorphOne instance, where I can call firstOrNew which returns an File instance and I'm able to call saveFile afterwards.
$model = $article->background_image()->firstOrNew([]);
$model->saveFile($file);
Related
I am using GitHub - jenssegers/laravel-mongodb: A MongoDB based Eloquent model and Query builder for Laravel;
In my Laravel project I created DB model that sets Model table name dynamically (in Mongodb case collection) .
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class DbData extends Model
{
protected $collection = 'default_collection';
function __construct($collection)
{
$this->collection = $collection;
}
}
This works when I am creating new DbData object, for data insert:
$data = new DbData('dynamic_collection_name');
$data->variable = 'Test';
$data->save();
But this solution is not enough of I want to use this DbData model for querying data from my database.
What I want to achieve is to add possibility to pass variable for DbModel, for instance something like this:
$data = DbData::setCollection('dynamic_collection_name');
$data->get();
You could perhaps do something like this on your class.
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class DbData extends Model
{
protected $collection = 'default_collection';
public function __construct($collection)
{
$this->collection = $collection;
}
public static function setCollection($collection)
{
return new self($collection);
}
}
This will allow you to call DbData::setCollection('collection_name') and the collection name will only be set for that specific instance.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class DbData extends Eloquent
{
use HasFactory;
// if you need to set default collection also then uncomment below line.
// protected $collection = 'defaultCollectionIfWantsToSet';
/**
* set collection name
*
* #param string $collection
* #return $this
*/
public static function setCollection($collection)
{
$instance = new self();
$instance->collection = $collection;
return $instance;
}
// OR you can use function as like below also
// public static function setCollection($collection)
// {
// $instance = new self();
// return $instance->setTable($collection);
// }
}
this will allow you to call DbData::setCollection('collection_name') and the collection name will only be set for that specific instance
I tested with Laravel 8 & 9
Laravel documentation suggests the following way to set up an eloquent model:
$user = user::with($conditions)->first();
What if I want to set up my eloquent model inside the model itself:
$user = new user();
$user->setup($conditions);
// class definition
class user extends Eloquent{
public function setup($conditions){
// load current object with table data
// something like
$this->where($conditions)->first();
// previous line output is dangling, is ok to assign it to $this variable?
}
}
If you're extending from Eloquent model, you may try the following approach. I assume you have a unique id column.
public function setup($conditions)
{
$model = self::with($conditions)->first();
if (! is_null($model)) {
$this->exists = true;
$this->forceFill(self::find($model->id)->toArray());
}
return $this;
}
Hope this solve your issue.
I have a Link model, which needs a field that refers to either the Page, Redirect or Gallery model. I would like to be able to do something line $link->obj and have that return either the Page, Redirect or Gallery object depending on which one was saved to it.
Polymorphic relations appear to be what I'm looking for, except that I can't seem to get this approach to work.
Current code
<?php
$item = Page::find (1);
$link = new Link ();
$link->linkable ()->save ($item);
$link->save ();
Models
<?php
class Link extends Eloquent
{
protected $table = 'link';
public function linkable ()
{
return $this->morphTo ();
}
}
class Page extends Eloquent
{
protected $table = 'page';
public function linkable ()
{
return $this->morphOne ('Link', 'linkable');
}
}
class Redirect extends Eloquent
{
protected $table = 'redirect';
public function linkable ()
{
return $this->morphOne ('Link', 'linkable');
}
}
class Gallery extends Eloquent
{
protected $table = 'gallery';
public function linkable ()
{
return $this->morphOne ('Link', 'linkable');
}
}
The link database table has linkable_id and linkable_type fields.
I suppose I must be misunderstanding the documentation, because this does not appear to work.
You're close. Assuming you have your database setup correctly, the only issue I see is you calling save() on the morphTo relationship.
The morphTo side of the relationship is the belongsTo side. The belongsTo side does not use the save() method, it uses the associate() method.
So, the code you're looking for should be something like:
$item = Page::find(1);
$link = new Link();
$link->linkable()->associate($item); // associate the belongsTo side
$link->save();
// and to show it worked:
$link->load('linkable');
$page = $link->linkable;
echo get_class($page); // prints "Page"
I'm following a course for Laravel 4 and the teacher did a code refactoring and introduced a magic method constructor in the controller
class UtentiController extends BaseController {
protected $utente;
public function __construct(Utenti $obj) {
$this->utente = $obj;
}
public function index() {
$utenti = $this->utente->all();
return View::make('utenti.index', ["utenti" => $utenti]);
}
public function show($username) {
$utenti = $this->utente->whereusername($username)->first(); //select * from utenti where username = *;
return View::make('utenti.singolo', ["utenti" => $utenti]);
}
public function create() {
return View::make('utenti.create');
}
public function store() {
if (! $this->utente->Valido( $input = Input::all() ) ) {
return Redirect::back()->withInput()->withErrors($this->utente->messaggio);
}
$this->utente->save();
return Redirect::route('utenti.index');
}
}
Thanks to this code I don't have to create a new instance of the Utenti model every time:
protected $utente;
public function __construct(Utenti $obj) {
$this->utente = $obj;
}
Now I can access the database with this simple approach:
$this->utente->all();
Whereas before, I had to do this:
$utente = new Utente;
$utente::all();
Does this type of technique have a name? (is it a pattern?).
My understanding is that every time the controller is invoked it automatically generates an instance of the User class (model) and applies an alias (reference) attribute $utente
Is that correct?
Also, here is the code for the Utenti model:
class Utenti extends Eloquent {
public static $regole = [
"utente" => "required",
"password" => "required"
];
public $messaggio;
public $timestamps = false;
protected $fillable = ['username','password'];
protected $table = "utenti";
public function Valido($data) {
$validazione = Validator::make($data,static::$regole);
if ($validazione->passes()) return true;
$this->messaggio = $validazione->messages();
return false;
}
}
This is called dependency injection or short DI. When creating a new instance of the Controller, Laravel checks the constructor for type hinted parameters (The ones that have a type defined like __construct(Utenti $obj){) If your controller has any of these Laravel tries to create an instance of the class and injects it into the constructor.
The reason why this is done is that it's becoming very clear what the dependencies of a class (in this case your controller) are. It gets especially interesting if you type hint an Interface instead of a concrete class. You then have to tell Laravel with a binding which implementation of the interface it should inject but you can also easily swap an implementation or mock it for unit testing.
Here are a few links where you can get more information:
Laravel docs IoC container
Method dependency injection in Laravel 5
StackOverflow - What is Inversion of Control?
I am working on creating models for a module I'm developing but I've run into a problem echoing out the result from a query.
What I get when using a var_dump() calling the the model in the block is NULL
I don't understand because in the resource model, if i do an echo $select it prints out the query which I enter into phpMyAdmin and it find the row. I think i must be trying to output the row wrongly.
This is my resource model:
class MyCompany_Facebook_Model_Resource_Facebookcoupon extends Mage_Core_Model_Resource_Db_Abstract
{
protected function _construct()
{
$this->_init('facebook/facebookcoupon', 'entity_id');
}
public function loadByField($field,$value)
{
$table = $this->getTable('facebook/facebookcoupon');
$where = $this->_getReadAdapter()->quoteInto("$field = ?", $value);
$select = $this->_getReadAdapter()->select()->from($table,array('facebook_id'))->where($where);
$id = $this->_getReadAdapter()->fetchOne($select);
return $id;
}
This is my model
class MyCompany_Facebook_Model_Facebookcoupon extends Mage_Core_Model_Abstract
{
protected function _construct()
{
parent::_construct();
$this->_init('facebook/facebookcoupon');
}
public function loadByField($field,$value)
{
$id = $this->getResource()->loadByField($field,$value);
$this->load($id);
}
}
and i call it using this block
class MyCompany_Facebook_Block_Content extends Mage_Core_Block_Template
{
private $couponCode;
public function displayCoupon($test)
{
$facebookid = Mage::getModel('facebook/facebookcoupon')->loadByField('facebook_id', '14547854');
var_dump($facebookid);
Adrock.use the below for more suitable solution
$model = Mage::getModel('facebook/facebookcoupon') ->getCollection()
->addFieldToFilter('facebook_id', 14547854) ->getFirstItem();
// here you'll get a collection but single record -
Please note:
loadByField($field,$value) in resource model is wrong.you can use load()
function only whenever,you will be trying to fetch data using primary key.