This forum has moved to a new location and is in read-only mode. Please visit talk.octobercms.com to access the new location.
Hi, I'm storing in database a field named "day_of_the_week" which represent as an integer from 1 to 7 the day of the week (can't be more explicit :) ).
In my model I'm using a function which is native in Laravel to create a custom attribute on the model which contains the day name as a string
public function getDayOfTheWeekAsStringAttribute() {
$days = [
1 => 'Monday',
2 => 'Tuesday',
3 => 'Wednesday',
4 => 'Thursday',
5 => 'Friday',
6 => 'Saturday',
7 => 'Sunday'
];
return $days[$this->day_of_the_week];
}
In my columns.yaml I'm using a partial path to display this custom field:
columns:
day_of_the_week:
label: 'romainmazb.appointment::lang.openinghours.labels.day_of_the_week'
type: partial
sortable: true
path: ~/plugins/romainmazb/appointment/controllers/openinghours/partials/days_of_the_week.htm
<?= $record->day_of_the_week_as_string ?>
But of course, if I'm here, it's because that doesn't work, I tried to dd($record)
and my custom attributes isn't present in the model.
How to achieve this?
And also, is there another easier way to render this data? Create a partial to render just one value is kind of ugly IMO...
Thanks for any advice!
[EDIT] I accomplished what I wanted to do with a better approach, using the lang files:
<?= Lang::get('romainmazb.appointment::lang.openinghours.labels.day' . $record->day_of_the_week); ?>
But I still want to know how to create custom calculated attributes in octobercms models?
Thanks again :]
Last updated
This code should work
<?= $record->day_of_the_week_as_string ?>
However this code will not know about your custom attribute
dd($record)
You must tell the model about your custom attribute by adding it to the $appends
property
/**
* The accessors to append to the model's array form.
*
* @var array
*/
protected $appends = ['day_of_the_week_as_string'];
Now it should appear on the model as a regular attribute
Last updated
daftspunk said: You must tell the model about your custom attribute by adding it to the
$appends
property/** * The accessors to append to the model's array form. * * @var array */ protected $appends = ['day_of_the_week_as_string'];
Now it should appear on the model as a regular attribute
Here was the trick! It works perfectly. Didn't think to use it since in Laravel it's for the serialization... Thanks.
Any talks about the minor question about creating a partial just to render this custom value? I know how to do it, but it seems to me to be kind of ugly, one file for one value... I thougt maybe it would be more easier to just have a field in plugin builder for this (model's attribute which does not come from the database).
[EDIT] Found the solution in the octoberCMS documentation and in the Laravel API for those who are interested:
// In your plugin's controller
public function listExtendRecords($records)
{
// Parse the collection the field
$parsed_records = $records->getCollection()->transform(function ($record) {
// Apply modification, in my case day_of_the_week with string render from lang file
$record->day_of_the_week = Lang::get('romainmazb.appointment::lang.openinghours.labels.day' . $record->day_of_the_week);
return $record;
});
// Return the paginator as it was at the beginning with the modified records
return new Paginator($parsed_records, $records->total(), $records->perPage(), $records->currentPage());
}
Then you can use in the plugin builder the field as you usually do: just fill the field name from database and it's type.
Last updated
Define it in your columns.yaml like this...
columns:
day_of_the_week_as_string:
label: 'romainmazb.appointment::lang.openinghours.labels.day_of_the_week'
Should work.
neilcarpenter said:
columns: day_of_the_week_as_string: label: 'romainmazb.appointment::lang.openinghours.labels.day_of_the_week'
I tried something like that before...
In this case, how do I reference it into the models columns builder? I can't set the field name as day_of_the_week_as_string
because it doesn't exist in database. The value from
field doesn't work neither.
Last updated
I've never actually used the Builder plugin - Which i'm assuming you're talking about?
The autocomplete feature isn't showing you your custom attribute name because it's not in the database.... like you said.
However the docs say this...
The Field property column has an autocompletion feature attached. It allows you to select columns from the database table that is bound to the model. At the moment it doesn't show relation properties, but you can still type them in manually.
Which kind of makes me think you don't have to choose an option from the auto complete.
So just type out "day_of_the_week_as_string" manually and try that.
I tried:
-
modify directly the yaml file: when displaying the list, October is trying to select day_of_the_week_as_string from the table
-
Insert directly in builder day_of_the_week_as_string: can't validate, October says directly it's unable to find to field in table.
Seems like due to OctoberCMS limitation, my solution is not the better one, but the only one maybe...
It's really not the most efficient way, but it works...
// In your plugin's controller
public function listExtendRecords($records)
{
// Parse the collection the field
$parsed_records = $records->getCollection()->transform(function ($record) {
// Apply modification, in my case day_of_the_week with string render from lang file
$record->day_of_the_week = Lang::get('romainmazb.appointment::lang.openinghours.labels.day' . $record->day_of_the_week);
return $record;
});
// Return the paginator as it was at the beginning with the modified records
return new Paginator($parsed_records, $records->total(), $records->perPage(), $records->currentPage());
}
Last updated
Something isn't right because I've 100% done something similar to what you're trying to do by just defining it in my columns.yaml file and then having a getWhateverAttribute()
on the model.
If you do this,
columns:
day_of_the_week_as_string:
label: 'romainmazb.appointment::lang.openinghours.labels.day_of_the_week'
And then have this in your model
public function getDayOfTheWeekAsStringAttribute()
{
$days = [
1 => 'Monday',
2 => 'Tuesday',
3 => 'Wednesday',
4 => 'Thursday',
5 => 'Friday',
6 => 'Saturday',
7 => 'Sunday'
];
return $days[$this->day_of_the_week];
}
What error do you get when trying to view the list in the backend?
Woaw you pointed something really weird:
Using this columns.yaml:
columns:
day_of_the_week:
label: 'romainmazb.appointment::lang.openinghours.labels.day_of_the_week'
type: text
sortable: true
open_at:
label: 'romainmazb.appointment::lang.openinghours.labels.open_at'
type: time
close_at:
label: 'romainmazb.appointment::lang.openinghours.labels.close_at'
type: time
day_of_the_week_as_string:
label: 'romainmazb.appointment::lang.openinghours.labels.day_of_the_week'
You are right: all work as expected: day_of_the_week as an integer, and _as_string as a string. So I wanted to delete day_of_the_week, which becomes useless:
columns:
open_at:
label: 'romainmazb.appointment::lang.openinghours.labels.open_at'
type: time
close_at:
label: 'romainmazb.appointment::lang.openinghours.labels.close_at'
type: time
day_of_the_week_as_string:
label: 'romainmazb.appointment::lang.openinghours.labels.day_of_the_week'
Still work, but I want the day_of_the_week_as_string to render to the first column:
columns:
day_of_the_week_as_string:
label: 'romainmazb.appointment::lang.openinghours.labels.day_of_the_week'
open_at:
label: 'romainmazb.appointment::lang.openinghours.labels.open_at'
type: time
close_at:
label: 'romainmazb.appointment::lang.openinghours.labels.close_at'
type: time
Here it blows up:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'day_of_the_week_as_string' in 'order clause' (SQL: select
romainmazb_appointment_opening_hours
.* fromromainmazb_appointment_opening_hours
order byday_of_the_week_as_string
desc limit 20 offset 0)
This was why I thought it wasn't working... I always tried to place it at the first column and all my tries failed.
Why?
Using ID as the first column works, seems like October want to pass my day_of_the_week_as_string as primary key maybe?
Last updated
Ah I think it might be because you're trying to sort by day_of_the_week_as_string
Try setting sortable: false
for that column in your columns.yaml
Maybe by default october orders by the first sortable column.
You can override this in your config_list.yaml
by setting the defaultSort property.
# Default sorting column
defaultSort:
column: created_at
direction: desc
Last updated
Yeah! It was that! Thanks you neilcarpenter.
My final columns.yaml, with invisible but sortable day_of_the_week so my list is filtered by the day_of_the_week_as_string in order from Monday to Sunday:
columns:
day_of_the_week:
type: number
invisible: true
day_of_the_week_as_string:
label: 'romainmazb.appointment::lang.openinghours.labels.day_of_the_week'
type: text
open_at:
label: 'romainmazb.appointment::lang.openinghours.labels.open_at'
type: time
close_at:
label: 'romainmazb.appointment::lang.openinghours.labels.close_at'
type: time
defaultSort:
column: day_of_the_week
direction: asc
This is much prettier than my solution! I love that clean way :)
1-12 of 12