In our previous post we installed Laravel 4.2, created a very simple auth system and configured Frozennode administrator to edit the users model, in this second part we’ll build a real(ish) world case creating a model with some relationships and see how it performs on the administrator.
First, so you can know about the app structure, we’re talking about a small part of a remake of this site under Laravel. In this case we’re talking about 2 tables and pivot one linking them. Enemy and Item and a pivot table is Enemy item drops. An enemy can drop one of multiple items, and items can be drop by many enemies.
Enemy
- name: string
- name_jp: string
- is_rare: string
- image: string
Item
- name: string
- name_jp: string
- desc: text
- desc_jp: text
- rarity: integer
- max_stack_on_hand: integer
- max_stack_in_storage: integer
- is_arks_cash: boolean
- is_tradable: boolean
- account_bound_on_equip: boolean
- is_account_bound: boolean
- can_be_dropped: boolean
- can_be_sold: boolean
- can_be_exchanged: boolean
- can_be_fed_to_mag: boolean
- buy_price: integer
- sell_price: integer
- notes: text
- image: string
Drop
- enemy_id: integer
- item_id: integer
- drop_rate: float
Now that we know what we’re gonna build let’s start creating those database migrations.
php artisan generate:migration create_enemies_table --fields="name:string, name_jp:string, is_rare:string, image:string"
php artisan generate:migration create_items_table --fields="name:string, name_jp:string, desc:text, desc_jp:text, rarity:integer, max_stack_on_hand:integer, max_stack_in_storage:integer, is_arks_cash:boolean, is_tradable:boolean, account_bound_on_equip:boolean, is_account_bound:boolean, can_be_dropped:boolean, can_be_sold:boolean, can_be_exchanged:boolean, can_be_fed_to_mag:boolean, buy_price:integer, sell_price:integer, notes:text, image:string"
php artisan generate:pivot enemies items
When running migrations using Jeffrey Way’s generators make sure there’s a space between the comma and the next field like this “name:string, name_jp:string”. If you input something like “name:string,name_jp:string” you’ll get a weird output.
Since Laravel generators don’t allow us to add fields directly on pivot tables let’s open our pivot table migration on app/database/migrations/ and add the drop_rate value and leave the up function like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
With our schema built, let’s migrate our database and start generating our models.
php artisan migrate
php artisan generate:model Item
php artisan generate:model Enemy
And now we’ll add the relationships on both of them.
So app/models/ Enemy.php and Item.php will end like this respectively.
1 2 3 4 5 6 7 8 9 10 |
|
1 2 3 4 5 6 7 8 9 10 11 |
|
Probably you’re wondering whats that withPivot doing. By default getting a privot table using the –>pivot attribute (you’ll see it in action the next example) only gets the keys, so we need to directly specify we want the drop rate.
Now let’s see how these in action just using code (you can skip this since it’s not related to the admin but just an example of how this works).
Replace the / route with this new function on /app/routes.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
I think the code is self explanatory with those comments, but in TLDR, we create an item, an enemy then we link them using attach, twice (one without drop rate and another with it), we display them and then we clean the relationships.
If you run the base url now you’ll probably see something like:
TestDrop: drop rate is: 0.00
TestDrop: drop rate is: 12.34
With that simple example done let’s build our admin panel. To do that we’ll need to create the item.php and enemies.php in /app/config/administrator/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
|
After creating those two files remember to add the item and enemy values to the menu array in app/config/packages/frozennode/administrator/administrator.php
It’s possible that you will be getting the following exception when going to the Item and Enemy admin pages: BadMethodCallException Call to undefined method Illuminate\Database\Query\Builder::isSoftDeleting() this is a small issue with Administrator and laravel 4.2, so depending if they patch this up you’ll probably need a newer version of administrator or apply this patch by yourself. Make sure you read my comment on that commit, or you’ll find problems later on.
With these possible issues resolved let’s explain this a bit. As with the Users models from our previous tutorial, we have two big sections, columns and edit_fields, but now we also have a filters section.
If you’re wondering filters work, it’s exactly the same as the edit_fields, except the image type field does not work with them (you couldn’t filter by image anyway).
We’re gonna center ourselves on the relationships, since it’s the most complicated but if you want to see details of the other options i’ve set for the columns (like the image preview) check this documentation link and if you’re curious about the edit_fields types check this one and the Field Types submenus on the left side of that page. Their docs are really neat and with clear examples. So let’s get into the relationships.
Getting back into our column view, to get data from related columns we use this.
1 2 3 4 5 |
|
We have two new mandatory options here. Relationship is always the method we created on the model and select works like a query. The (:table) value will always reference to the related table.
Also it will affect all values on toMany relationships so it returns a field on toOne ones. What does this mean? In our case doing ‘(:table).name’ wouldn’t return anything since it would return one or more than one field, so we use a SQL aggregation function. But if we had a one to one relationship we could return the name (we’ll see an example soon).
Now let’s see how this works on edit_fields.
1 2 3 4 5 |
|
As a type we have relationship, and then we have a value named name_field. Thats the column from the related table that you want to show to the user. In our case since the item name is the most useful to assign things we use it.
If you see we also use the ‘drops’ model method as the array key to define the column.
Now, you may have realised that with this setup we can’t set the drop rate values on the pivot table.
That means that we need to setup a new administrator view to be able to set those views and a new model. So lets build them.
php artisan generate:model EnemyItem
Time to edit the model.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Since it’s a pivot table we add the enemy and item relationships. Now let’s create a “enemyitems.php” admin menu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
|
As you can see it’s pretty similar but this is the case where on our relations we can use ‘select’ => ‘(:table).name’ on the column name and we’ll get the Item name and the enemy name since our relationship is many to one on both item and enemy.
And finally, add this new administrator to the menu config array on administrator.php and we’re done
Before finishing just some tips.
Administrator lets you do more things with relationships so make sure you check the documentation to get a more deeper insight, but what we’ve been covering here should be useful for basic admin panels.
While it looks like we did a lot of code, if you use sublime text, it’s multicursor is extremely useful to create this really fast from the field lists we had at the beginning of this post.
As i said on the first part of this tutorial if you want to use sentry or any auth library with frozennode administrator you can without issues, just check this to see how to do it.
That’s all, we’re done with this two part tutorial. I Hope it was useful.
As with the previous one you can access the repo of this tutorial by clicking here