Laravel 5. Query from a existing model instance? - php

Now I get some model with all properties filled except one.
So I want to make a search in a database and see if there is some registry that matches all the properties values, in which case, get the last property value and keep it.
Now im doing a query wit query builder, giving it all where like this:
$query->Model::select()->where(field, $instance->field);
$query->where(field2, $instance->field2);
...
$query->get();
But I want to know if there some way to make a shortcut like...
$instance->get();

Yes you can do this by defining method in your model like this
class YourModel extends Model
{
public function getFiltered()
{
return Model::where('field1',$this->field1)->where('field2',$this->field2)->get();
}
}
And you can access it like this:
$instance->getFiltered();
You cannot keep function name 'get' because It's already being used in Model which is being extended. But you can change from getFiltered to anything which is not used. Like If the Model was User and the function getFiltered gives user's comments then It can be comments.

Related

Using a query scope in a collection laravel

My Association model looks like this (irrelevant code redacted):
class Association extends Model
{
public function members() {
return $this->hasMany('App\Member');
}
}
My Member model looks like this:
class Member extends Model
{
public function scopeActive($query) {
return $query->where('membership_ended_at', Null);
}
public function scopeInactive($query) {
return $query->whereNotNull('membership_ended_at');
}
}
This is what I want to be able to do:
$association = Association::find(49);
$association->members->active()->count();
Now, I'm aware there's a difference between a Query and a Collection. But what I'm basically asking is if there's some kind of similar scope for collections. Of course, the optimal solution would be to not have to write TWO active methods, but use one for both purposes.
(question already answered in the comments, but might as well write a proper answer)
It is not possible to use a query scope in a Colletion, since query scope is a concept used in Eloquent to add constraints to a database query while Collections are just a collection of things (data, objects, etc).
In your case, what you need to do is to change this line:
$association->members->active()->count();
to:
$association->members()->active()->count();
This works because when we call members as a method, we are getting a QueryBuilder instance, and with that we can start chaining scopes to the query before calling the count method.

Laravel 4: Model Relationships Not Working (sort of)?

I have 3 models in my Laravel 4 project: Employee, EmployeeClass, Employer:
class Employee extends Eloquent {
protected $table = 'users';
public function employee_class () {
return $this->belongsTo('EmployeeClass', 'employee_class_id');
}
}
class EmployeeClass extends Eloquent {
protected $table = 'employee_classes';
public function employees () {
return $this->hasMany('Employee');
}
public function employer () {
return $this->belongsTo('Employer');
}
}
class Employer extends Eloquent {
protected $table = 'employers';
public function employee_classes () {
return $this->hasMany('EmployeeClass');
}
}
The EmployeeClass relationships work as expected. I can execute EmployeeClass::find(1)->employees; or EmployeeClass::find(1)->employer; and it returns the object.
Trying to make the same calls on the other two (to retrieve the relationship to EmployeeClass) doesn't work. Both of these lines return empty sets:
Employee::find(1)->employee_class;
Employer::find(1)->employee_classes;
However, the weird thing is, both of these lines work correctly:
Employee::find(1)->employee_class()->first();
Employer::find(1)->employee_classes()->first();
The first example returns NULL (I believe it should be returning a Collection). The second example returns an EmployeeClass object (the expected instance).
I want to point out that there is one entry in each table with an id of 1, and each one is set up with the FK = 1 as well, so they should join properly. In fact, I think the fact that EmployeeClass works correctly, and the fact that getting the query and executing it (in the second, successful, set of code) does as well, sort of proves that.
I'm sure I'm just doing something stupid; maybe another set of eyes will help!
I can use the workaround (the second set of code) since it seems to be working but I'd like to get it clean and correct if at all possible...
For multi-word relationships, the function should be in camelCase (in fact, all class methods should). When accessing a model's attributes, it is still allowed to access the relationship name in snake case (in your example, 'employee_class', but note that this bypasses all eager loading and you should access the relationship in exactly the same case as the relationship method's name.
In your example, if you rename the employee_class(es) functions to employeeClass(es), everything should work.
// gets all employees and their class(es). the argument(s) for with()
// MUST match the names of the methods exactly.
Employee:with('employeeClass')->get();
// you MUST access eager loaded data in the same case as in with().
// if you access via snake case, eager loading is bypassed.
$employee->employeeClass;
// this also works but should generally be avoided.
Employee::find(1)->employeeClass()->first();

Laravel 4 Model Methods access

am I doing something wrong to be able to access Methods stored in a model in a view. For Example. My User model has a method that looks like
public function isCustomer(){
if (isset($this->customer_id))
return true;
else return false;
}
When I try to access this in the view I end up with Call to a member function getResults() on a non-object.
View code is something like
#if($user->isCustomer)
Something
#endif
Is the model ONLY for database relationships between models or can I store my own class functions here as well?
The function i listed is one of the basic ones. I have quite a few more complicated functions that I would like to run from my User class but am not sure how, as i end up with the same error each time. Should they be stored in the controller?
You can store class functions there. By first glance it looks like your missing () on isCustomer. If it were me I would store that in the controller, like:
$customer = $user->isCustomer();
then pass that to the view.

How to apply conditions to a with relationship in laravel 3?

I have a pair of objects in laravel, pages and contents.
I have setup a relationship function, and include, which includes contents based on page_id.
I want to apply other conditions such as where deleted - 0, and where dates are within certain bounds, I know how to apply where conditions and set these field up.
What I can't fathom is how extra conditions can be applied as well as matching relationship fields.
Could anybody help me with this?
Defining the relationship in the model is all you need to do to the model itself. However you can add a static function to the model to get the data with the information you need.
Page model methods examples:
class Page extends Eloquent {
public function contents()
{
return $this->has_many('Content');
}
// Return all content that has not been marked as
// deleted in the database
public static function with_contents($id)
{
return Page::find($id)->contents()
->where_null('deleted')
->get();
}
}
This example assumes that the deleted field in the contents table is null unless it is deleted, in which case it will have any value.
To use you would simply use
$page = Page::with_contents('1');
You can create as many of these static helper methods as you like or add as many conditions to the one method as you like, then use your new static methods to retrieve your data.
I think this might be what you're looking for
http://doginthehat.com.au/2012/06/adding-conditions-to-relationships-in-laravel/
class User extends Eloquent {
public function meta()
{
return $this->has_many('Meta','target_id')
->where('target_type','=',$this->table());
}
}

Hide columns when serializing via toArray()

I have a simple problem where I often return CRUD type Ajax requests with array serialized versions of Doctrine 1.2 models. I'd love to be able to simply return the toArray() method after the execute() result, however, this will display data about my models that I don't wish to expose. A simple example is on my user model the password and salt get displayed. While I realize those are already hashed values, it's something I'd rather not return as a JSON response.
I've poured over the Doctrine 1.2 manual, but did not find anything that offered the type of functionality I'm looking for. I realize I can iterate over the result to manually unset() the columns I wish to hide, but I'm hoping a more native solution is out there that I've overlooked.
Why don't you build your own toArray() ?
If you want to do that, you will have to extends the sfDoctrineRecord class that inherit from all Base* class. It is describe in the doc.
You have to put the configureDoctrine() inside config/ProjectConfiguration.class.php.
Then you will have a class like that:
class myDoctrineRecord extends sfDoctrineRecord
{
}
So you can easily add your custom toArray() here:
class myDoctrineRecord extends sfDoctrineRecord
{
public function toArray($deep = true, $prefixKey = false, array $excludeFields = array())
{
// do every thing like the original toArray
// but when a column match one entry in $excludeFields, don't add it
}
}
So, when using the toArray() method with an array of fields for the third parameters, they will be excluded from the result.

Categories