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.
Related
there is an instance of \Illuminate\Database\Eloquent\Builder that I would like to persist when instantiate (during the mount lifecycle hook) so that I can use it for queries. The problem is I would not be able to set it as public property since it will throw a Livewire\Exceptions\PublicPropertyTypeNotAllowedException (as follows). I would not be able to save it in session as well since it is a PDO instance and PDO instances can't be serialized or unserialized.
Any idea guys?
Edit:
Controller:
public function index() {
$tableQuery = User::query();
return view('table', compact('tableQuery'));
}
table.blade.php:
<livewire:table
:tableQuery=$tableQuery
>
App\Http\Livewire\Table:
class Table extends Component{
private $tableQuery;
public function mount($tableQuery){
$this->tableQuery = $tableQuery;
}
public function render(){
return view('livewire.table');
}
}
you can use Model inside livewire
class Table extends Component{
public $tableQuery;
public function mount(){
$this->tableQuery = User::query();;
}
public function render(){
return view('livewire.table');
}
}
I have a models.php page that contains the specification of form for a specific model.
models.php
$books = [
['Book Name', 'text' ],
['Author', 'text']
];
$vegetables = [
['Name', 'text'],
['Photo', 'file']
]
Now this page is accessed by an admin.php page, which generate an appropriate HTML form on the basis of the given name and input type.
I want to fill the form and send the data into a handle.php and handle the data with the specific function to fill the data into appropriate table.
handle.php
function books(){
// this will fill the details into table of books.
INSERT INTO BOOKS
name = $_POST['book_name']
author $_POST['author']
}
function vegetables(){
// this will fill the details into table of vegetables.
INSERT INTO VEGETABLES
name = $_POST['book_name']
photo = $_FILE['photo']
}
(If there's any other better way of doing this, so please mention, I'll do that way and delete my question.)
Here's my suggestion. As stated in the comments, this is just my way to do such things, it's not necessarily the best solution for every situation.
I have a base model, that defines all methods all model need to have in common. Here's a very simplified version:
class Model {
public $modelName = 'default';
public $id = null;
private $fields = [];
private $tableName = 'default';
private $tableDefinition = [];
private $idField = 'id';
public function insert($dataset) {
// do some database magic by using $this->fields, or $this->tableDefinition
$sql = "INSERT into {$this->tableName} ...";
...
return $id;
}
public function update($id, $dataset) {
// do some more database magic by using $this->fields, or $this->tableDefinition
}
// many more methods. To get data, delete, sort, ..
//...
}
Every model now extends this base model class and sets it's specific params, maybe even overrides some methods or adds special ones:
class Books extends Model {
public $modelName = 'book';
private $fields = ['bookName','Author'];
private $tableName = 'BOOKS';
private $tableDefinition = [
['bookName','varchar'],
['Author','varchar']
];
// private $idField = 'id'; // you can ommit that, if it's the default.
}
If Vegetables behaves different you can simply override a method:
class Vegetables extends Model {
public $modelName = 'vegetable';
// set all other properties...
// override insert() for example
public function insert($dataset) {
// do something that doesn't comply with the standard procedure
}
}
Then in handle.php you can do something like this:
<?php
$modelName = $request; // get it from your form, your url, ..
// & verify this model(file) exists.
$model = new $modelName();
$model->insert($dataSet);
Make a base interface BaseModel.php
which would have the basic signatures of insertion , updation and selection
Make a derived class booksModel.php and vegetablesModel.php that would implement the BaseModel class.
In this way, you have made your code extendable. If there is some common functionality, you can make the base class as Abstract class.
abstract class BaseModel {
abstract function add($dataObject);
abstract function get($dataObject);
}
class BooksModel extends BaseModel {
public function add($dataObject) {
/* Implementation */
}
public function get($dataObject) {
/* Implementation */
}
}
class VegetableModel extends BaseModel {
public function add($dataObject) {
/* Implementation */
}
public function get($dataObject) {
/* Implementation */
}
}
I'm new to laravel framwork , and I'm coding my first web app
and getting the following error
FatalErrorException in PersonController.php line 26:
Call to a member function getPaginate() on a non-object
this is my Controller
<?php
namespace App\Http\Controllers;
use App\Repositories\PersonRepository;
class PersonController extends Controller
{
protected $personRepo ;
protected $nbrPerPage = 4 ;
public function _construct(PersonRepository $personRepository)
{
$this->personRepo = $personRepository ;
}
public function index()
{
$persons = $this->personRepo->getPaginate(nbrPerPage);
$links = $persons->setPath('')->render();
return view('index', compact('persons', 'links'));
}
public function create()
{
}
public function store()
{
}
public function show($id)
{
//
}
public function edit($id)
{
//
}
public function update($id)
{
//
}
public function destroy($id)
{
//
}
}
and this my repository class
<?php
namespace App\Repositories ;
use App\Person ;
use App\User;
class PersonRepository {
protected $person ;
public function _construct (Person $person)
{
$this->$person = $person ;
}
public function getPaginate($n)
{
return $this->person-> paginate($n) ;
}
}
You are instantiating an empty instance of the Person model and then trying to call paginate() on it in your repository. However, paginate() is meant to be called on either a query builder object or an Eloquent query. Assuming that you want to return paginated results of all your models, you can scrap the $person property entirely as well as the constructor and then just change your method to this:
public function getPaginate($n)
{
return Person::paginate($n) ;
}
I will say that for such a simple query, I would suggest not using a repository altogether and just use Person::paginate($n) inside your controller, as Eloquent essentially functions as a repository already.
Unless these are just typos in the question, you have a lot of typos in your code.
The typo that is causing this specific error is that the name of the constructor method should be __construct (with two underscores), not _construct (with one underscore).
Since the constructor method is misspelled on your PersonController, this method is never called and the personRepo attribute is never set. Since it is never set, the line $persons = $this->personRepo->getPaginate(nbrPerPage); is trying to call getPaginate() on a non-object.
Additional typos/issues I see at a glance:
$persons = $this->personRepo->getPaginate(nbrPerPage);
nbrPerPage is being used as a constant. This is incorrect. Should be:
$persons = $this->personRepo->getPaginate($this->nbrPerPage);
Constructor on PersonRepository also misspelled. Should be __construct(), not _construct.
$this->$person = $person ;
This is inside the attempted construct of the PersonRepository. The $ needs to be removed from $this->$person. Should be:
$this->person = $person;
I have a model which contains many methods.
class UserModel extends Eloquent{
private $active;
function __construct() {
$this->active = Config::get('app.ActiveFlag');
}
protected $table = 'User';
protected $fillable = array('usr_ID', 'username');
public function method1(){
//use $active here
}
public function method2(){
//use $active here
}
}
Controller:
$user = new UserModel($inputall);
$user->save();
Without constructor, it works fine. However, with constructor it doesn't save the user (the query which is generated doesn't have any fill attributes or values). The query is as follows:
insert into User() values();
Any inputs please?
Well yes, that's because you override the Eloquent constructor which is responsible to fill the model with values when an array is passed. You have to pass them along to the parent with parent::__construct():
public function __construct(array $attributes = array()){
parent::__construct($attributes);
$this->active = Config::get('app.ActiveFlag');
}
Your model's constructor doesn't accept any parameters - empty (), and you are creating new instance of UserModel in your controller adding $inputall as a parameter.
Try to refactor your contructor according to this:
class UserModel extends Eloquent {
public function __construct($attributes = array()) {
parent::__construct($attributes);
// Your additional code here
}
}
(Answer based on other Eloquent contructor question)
Is it possible to pass, somehow, a parameter to a relationship function?
I have currently the following:
public function achievements()
{
return $this->belongsToMany('Achievable', 'user_achievements')->withPivot('value', 'unlocked_at')->orderBy('pivot_unlocked_at', 'desc');
}
The problem is that, in some cases, it does not fetch the unlocked_at column and it returns an error.
I have tried to do something like:
public function achievements($orderBy = true)
{
$result = $this->belongsToMany (...)
if($orderBy) return $result->orderBy(...)
return $result;
}
And call it as:
$member->achievements(false)->(...)
But this does not work. Is there a way to pass parameters into that function or any way to check if the pivot_unlocked_at is being used?
Well what I've did was just adding new attribute to my model and then add the my condition to that attirbute,simply did this.
Class Foo extends Eloquent {
protected $strSlug;
public function Relations(){
return $this->belongsTo('Relation','relation_id')->whereSlug($this->strSlug);
}
}
Class FooController extends BaseController {
private $objFoo;
public function __construct(Foo $foo){
$this->objFoo = $foo
}
public function getPage($strSlug){
$this->objFoo->strSlug = $strSlug;
$arrData = Foo::with('Relations')->get();
//some other stuff,page render,etc....
}
}
You can simply create a scope and then when necessary add it to a builder instance.
Example:
User.php
public function achievements()
{
return $this->hasMany(Achievement::class);
}
Achievement.php
public function scopeOrdered(Builder $builder)
{
return $builder->orderBy(conditions);
}
then when using:
//returns unordered collection
$user->achievements()->get();
//returns ordered collection
$user->achievements()->ordered()->get();
You can read more about scopes at Eloquent documentation.
You can do more simple, and secure:
When you call the relation function with the parentesis Laravel will return just the query, you will need to add the get() or first() to retrieve the results
public function achievements($orderBy = true)
{
if($orderBy)
$this->belongsToMany(...)->orderBy(...)->get();
else
return $this->belongsToMany(...)->get();
}
And then you can call it like:
$member->achievements(false);
Works for the latest version of Laravel.
Had to solve this another was as on Laravel 5.3 none of the other solutions worked for me. Here goes:
Instantiate a model:
$foo = new Foo();
Set the new attribute
$foo->setAttribute('orderBy',true);
Then use the setModel method when querying the data
Foo::setModel($foo)->where(...)
This will all you to access the attribute from the relations method
public function achievements()
{
if($this->orderBy)
$this->belongsToMany(...)->orderBy(...)->get();
else
return $this->belongsToMany(...)->get();
}