I have a decent-size codebase built at this point. I have a couple of tables with matching Eloquent models that are storing addresses in the form ### Street, City, ST, xzipx
. These are represented in the database by a single varchar field called address
.
Now here's my issue. I want to add a new feature that allows items to be compared by whether they are in the same city, state, etc. The way to do this as my database is currently configured is to tokenize the address string. This is fine, but a little annoying to have to do it every time.
The ideal solution would be to restructure the database, and associated models, to split the address
field into street
, city
, state
, and zip
. The only problem there, would be that everywhere else, where I'm currently accessing the address using $model->address
, I would have to construct it from the pieces. This happens a lot throughout the code, so even creating a helper function as below:
public function address(){
return $this->street.", ".$this->city.", ".$this->state." ".$this->zip;
}
would mandate replacing all instances of $model->address
with $model->address()
, which would still be cumbersome. The ideal solution would be to create a dynamic property, like how Laravel creates them using for relationships. Is this possible?
Or is there a better solution?
Eloquent allows you to access your relations via dynamic properties. Eloquent will automatically load the relationship for you, and is even smart enough to know whether to call the get (for one-to-many relationships) or first (for one-to-one relationships) method.
The Eloquent ORM included with Laravel provides a beautiful, simple ActiveRecord implementation for working with your database. Each database table has a corresponding "Model" which is used to interact with that table. Before getting started, be sure to configure a database connection in config/database.
with() is for eager loading. That basically means, along the main model, Laravel will preload the relationship(s) you specify. This is especially helpful if you have a collection of models and you want to load a relation for all of them.
It effectively comes down to the following: for each table you have in your database, you create an Eloquent model. An Eloquent model is just a PHP class, that allows you to do two things: Interact with the database table as a whole. For example: $users = User::all(); gets all users.
You could define an accessor for the address
property:
class YourClass {
public function getAddressAttribute()
{
return $this->street.", ".$this->city.", ".$this->state." ".$this->zip;
}
}
Then, $object->address
should return what you need. If you want it to be included on the model's array and JSON forms, you'll need to add it to the $appends
property of the model.
class YourClass {
protected $appends = array('address');
public function getAddressAttribute()
{
return $this->street.', '.$this->city.', '.$this->state.' '.$this->zip;
}
}
EDIT: for setting, you would have to set up a mutator, like so:
public function setAddressAttribute($value)
{
// assume $this->handlesParsingAddress parses and returns an assoc array
$parsed = $this->handlesParsingAddress($value);
$this->street = $parsed['street'];
$this->city = $parsed['city'];
$this->state = $parsed['state'];
$this->zip = $parsed['zip'];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With