Repeat Mutators - laravel

I'm using several mutators that are basically the same on different models and within the same models, for different fields. eg: to tidy dates:
public function getStartShortDateAttribute()
{
return $this->start_time->format('d-m-y');
}
Is there a standard way to reuse the same mutator for several fields across models?

Use a trait, which is a way to reuse code across classes.
trait HasStartTimes {
public function getStartShortDateAttribute()
{
return $this->start_time->format('d-m-y');
}
}
Now you can use this trait in your class, with the use statement. When done it will include the traits function, in the classes that uses the trait. This is an design approach that is used already in Laravel, see AuthenticatesUsers.
class YourModel {
use HasStartTimes;
}

Related

Where can I store my big SQL queries in Laravel?

I have a problem in my Laravel structure because I need to add many reports to my app, so I think it's not a good idea to put everything in the controller because my eloquent models allow me to list, add, insert and update, and my queries need more than one table with joins, and some math functions like sum(), max(), min().
When I used Codeigniter, I added methods with each query in the model file.
So I can call it $sales->salesReport() and it gave me the data.
The question is really a matter of what is being done and what is responsible. There are some excellent posts on where logic should be kept and what can be used. I am a little unclear as to whether you are asking about chaining something like scopes or more just where to put your logic. I would probably have a service:
<?php
class SalesReportService {
public function generateReport(Sales $sales)
{
// logic here...
return $result;
}
}
and then in the controller it would be something like:
<?php
class SalesController extends Controller {
public function __construct(SalesReportService $reportService)
{
$this->reportService = $reportService;
}
public function show(Sales $sales)
{
return $this->reportService->generateReport($sales);
}
}
Laravel offers something similar to Codeigniter that matches what you described. It's called query scopes, or more precisely local scopes. You can keep them in your model and call them whenever you want.
You add in your model
public function scopeSalesReport($query) {
return $query->join(...);
}
Source: https://laravel.com/docs/5.4/eloquent#local-scopes

Symfony validator

My question is related to symfony validator component. I don't use forms. And I want to move validation rules for each entity to separated class (like AuthorVlidator, BookingValidator etc.). How can I move it to separated classes and define rules?
Thanks.
Why would you like to move it to separated classes? With annotations it pretty easy to use it.
It's not a good idea to do it, but if you really want to do it in other classes, you could add this method in each classes that you want to validate:
class YourObject
{
public static function loadValidatorMetadata(ClassMetadata $metadata)
{
YourObjectValidator::validate($this, $metadata);
}
}
And:
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints\NotBlank;
class YourObjectValidator
{
public static function validate(YourObject $object, ClassMetadata $metadata)
{
$metadata->addPropertyConstraint('name', new NotBlank());
}
}
If you want separate this logic for add validation depending on properties value, it's not the proper way to do it. You should read the doc, callback could be a solution.

what to do with an inverted polymorphic relation?

I have been trying to get my head around these polymorphic relationships all day. I might be over complicating/thinking it but. Can Laravel handle inverse polymorphic relationships? I have a registration flow that can have two types of field Models- normal field and customField.
When I loop through all the fields available it could pull the attributes from either NormalField or CustomField.
<?php
foreach($registrationFlow->fields->get() as $field)
{
echo $field->name; // could be custom field or could be normal field
}
?>
My difficulty is that, the example given in the docs works if you want to assign a photo to either staff or orders, but i want to assign either a customField or a normalField to a registrationFlow
*Edit
If you follow the example for the polymorphic many to many relationship, The tag class contains posts and videos- while i would want just a simple fields() method that relates to customField or normalField dependent on the type
First of all, you should take a look at the updated docs for Laravel 5.1: https://laravel.com/docs/5.1/eloquent-relationships#polymorphic-relations.
I think the difficulty with the example they provide is that the relationship between Photo and Staff/Product are "has-a" relationships, whereas you are trying to model an "is-a" relationship. However, you can model "is-a" essentially the same way. Take a look at this article: http://richardbagshaw.co.uk/laravel-user-types-and-polymorphic-relationships/.
Basically, the strategy is to define a generic model (and a generic table), perhaps in your case Field, that relates to your RegistrationFlow. You then have two subtype models, NormalField and CustomField, that have one-to-one relationships with Field. (there's your "is-a"). Thus, RegistrationFlow is indirectly related to your field subtypes.
Polymorphism comes in when you want to access the specific subtypes:
class Field extends Model {
public function fieldable()
{
return $this->morphTo();
}
}
Your base field table should have fieldable_id and fieldable_type columns defined (see the Eloquent docs).
You can then add methods to NormalField and CustomField that let you access the base model (your "inverse relationship"):
class NormalField {
public function field()
{
return $this->morphOne('Field', 'fieldable');
}
}
class CustomField {
public function field()
{
return $this->morphOne('Field', 'fieldable');
}
}
Usage:
$field = Field::find(1);
// Gets the specific subtype
$fieldable = $field->fieldable;

Laravel 4 Use the same Model and Controller for 12 lists for selects

I have to meke models, controllers and views for 12 tables. They have all the same structure id, name, order.
I was thinking and maybe using:
Controller
index($model)
$model::all()
return View::make(all_tables,compact('model'))
edit($model,$id)... and so on.
But and don't know if there's a way for using only one model.
Did anybody do anything like this?
Any idea?
Thanks
Although each model has the same table structure, what you're trying to achieve would not be advisable as you'd lose a lot of the fluent capabilities of Laravel's Eloquent ORM.
Regarding the controller, this would work:
<?php
namespace App\Http\Controllers;
use App\Http\Requests;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class GenericModelController extends Controller
{
public function loadModelById($model, $id)
{
$instance = \App::make('App\\' . ucfirst($model));
return $instance->find($id);
}
}
You'll need the following route:
Route::get('show/{model}/{id}', 'GenericModelController#loadModelById');
Example, to load a user with an id of 1:
http://www.yourdomain.com/show/user/1
Edit: I just saw that you're using Laravel 4, so the syntax for defining a route will be a little different I believe but the general concept will still work. Testing in Laravel 5 and works perfectly.
You should get get some idea from here.Please use the link below.
https://scotch.io/tutorials/a-guide-to-using-eloquent-orm-in-laravel
// app/models/Bear.php
class Bear extends Eloquent {
// MASS ASSIGNMENT -------------------------------------------------------
// define which attributes are mass assignable (for security)
// we only want these 3 attributes able to be filled
protected $fillable = array('name', 'type', 'danger_level');
// DEFINE RELATIONSHIPS --------------------------------------------------
// each bear HAS one fish to eat
public function fish() {
return $this->hasOne('Fish'); // this matches the Eloquent model
}
// each bear climbs many trees
public function trees() {
return $this->hasMany('Tree');
}
// each bear BELONGS to many picnic
// define our pivot table also
public function picnics() {
return $this->belongsToMany('Picnic', 'bears_picnics', 'bear_id', 'picnic_id');
}
}
I find a simple way.
Only one model, one controller and one view(index,edit, etc) too.
A single table with
id, name of list, value (name to appears in the list)
Yo pass can pass to de view all the values per list, and for any list in the table you can create de select if it's no empty.

Using phpspec to test two-way relationships that require pass by reference

I'm using phpspec to test my zend 2 module and having issues with testing pass-by-reference. I've read other topics about this that state it's bad design if you are having to do this. I disagree that this a blanket statement.
I need to represent a two-way relationship between classes where two classes have references two each other.
Is there a way for me to get phpspec to test this or is there a better design I need to consider.
I want to ensure that Class A can return Class B and vice versa.
This is not really a behaviour, but state verification. PhpSpec focuses on behaviour, but what you need to do is still possible:
class ASpec extends ObjectBehavior
{
function it_exposes_B(B $b)
{
$this->beConstructedWith($b); // or $this->setB($b);
$this->getB()->shouldReturn($b);
}
}
The BSpec would look similar:
class BSpec extends ObjectBehavior
{
function it_exposes_A(A $a)
{
$this->beConstructedWith($a); // or $this->setA($a);
$this->getA()->shouldReturn($a);
}
}

Resources