This episode is on a topic that I haven't really covered yet and have been planning to for a while, but there's a brand new gem out called administrate that we're going to talk about. This whole suite of things going forward. In the past, you've probably used ActiveAdmin or rails admin, both of which are pretty good gems, but I have plenty of complains about. ActiveAdmin specifically is the one that I've used the most, and while it's been reallly great, I've been able to use it and customize it pretty much in every application, some nifty things like these little state tags that can give people quick access to like visual colors on, weather or not the orders are completed or in progress like this. I have a lot of complains about the DSL that they designed for this. When you're building an admin, you would expect that a DSL would just like drop in things really quickly and easily it would be great, but it comes down to the application and what you're trying to accomplish with it every single time, so when you're building an application, you're going to have an admin interface that maybe needs graphs, or maybe needs a complicated form for you to manage this stuff in the back. This is not really the place to do it, most of the time you have to do it in this admin file and you have to customize these filters for example, and on the right side, by default they create filters for every single record. If you associate the customers, what if you have 10,000 customers and it turns out that this actually loads 10,000 customers in the sidebar and makes all your pages slow and everything. Then when you go to remove that filter, there's no way to do like AJAX loading and autocomplete, and ends up just being a lot more work and if you're able to just do this with your own views that you have access to, it would be so much more flexible and you can use the same tools that you used on the front end to build your admin. That's been my primary complaint about ActiveAdmin, it's so separate from your application, and the admin really shouldn't be so separate. I was planning on building a gem in the future for that solution, so I really wanted to scrap DSL's, I wanted to basically like admin scaffolding, where you'd be able to say: Look, there's users, go generate the scaffold for it, find all the fields and then generate views for me, and then make it so that I can go customize those. Thoughtbot beat me to the punch. They've built this wonderful new gem called administrate that so far I've been really enjoying, I've used in one application so far, it's got a lot to be desired, but it's getting there. Administrate has basically very little functionality right now. They have search at the top, and they have the models on the sides, and then you can edit and destroy and create your records, but that's about it. When you click on a customer, for example, you can customize this view pretty easily and add related orders and it will be able to load those, and then you'll also have access to the controllers and be able to, for example eager load these so that this page loads a lot faster by grabbing all of those in two queries instead of four queries or n+1 queries for example. This is definitely a really good start, there's a lot to be desired, and a lot of people are opening up new issues recommending: Why don't you support this or that, how do we go about adding in search so that you could replace the search with maybe ElasticSeach behind the scenes, so they're going about building this in a very very good way and I just wanted to show this off because I think if we can support this, I would love to see where this ends up going, because for me, personally, ActiveAdmin has been kind of a pain to use every single application that ends up needing an admin.
Let's go ahead in this episode and install administrate. In our previous episode, the Stripe subscriptions episode, we built the UI for the customers for that, but what if we build an admin interface to be able to watch and see the users and their subscriptions come through and see how administrate has you do that. We're going to install administrate now in that application and see how it works.
In the documentation there's a link to their documentation Heroku app, which gives you all the instructions that you will probably need that will be basically what we're going to cover in this episode. Take a look at that and we're just going to go through and follow this, I'm going to add the latest version of the gem to the gemfile, so I'll open up that, we'll go down here at the bottom and we'll say
gem 'administrate' and we'll save that and run
bundle install to install it. Once the bundle is installed, we can paste in the administrate install generator, and this will go through and look at all of the models that we have and generate a few files. Don't be afraid, with this gem, you're going to want to jump into all of those and check them out. Let's start the routes. This is one of the nice things about this gem, is that it just plugs it into a normal namespace route instead of mounting an engine you can't really customize, they're just normal routes, this is intended to be treated just like part of your own application, and that's what I really really like about this. If you wanted to, change the namespace from /admin to like superadmin, you can do that, and you can just change this, and then you would also change the related scope or the parent class in the controllers. This is cool, it loads the dashboard manifest, which is a file in app/dashboards that you get as part of this gem, and the dashboard manifest just defines a list of dashboards that are available and it goes through each of those and dynamically makes
resources routes for those. So it just has symbols for all the names, and then basically does that for you, so rather than you manually specifying stuff like that in your routes, it will just dynamically load those, which is super cool, because if you run your rails server and you decide: Let's go into the dashboard manifest and we don't want to see charges in our dashboard, and you can comment that out if you go into your localhost:3000/admin, once that loads, you'll be able to see that the charges no longer exist, and maybe come back later and you're like: Yeah, we should have charges in our admin, you uncomment it, you refresh the page and you have charges and that's it. That's super duper cool, I really really like that, all of this is just plain old ruby classes, they don't even inherit from anything special, it's just the way for you to organize that, so the routing is super simple, the route dashboard points the root dashboard, so you can either make this grab the first one or you can hard code it and say like: Episode should be like the first one there, so if you refresh that, then when you come to admin, you'll see episodes by default instead. That's cool, you can even go into your routes and comment out like the route and you can have it force or redirect to episodes or something like that if you wanted. I really really like how simple the manifest is, and then that brings us to each of the dashboards themselves, so you get an admin controllers folders, which is useful, but you also get a dashboard for each one of those, and we'll talk about how those work together, you also do not get views by default. Let's talk about how these work.
We'll take a look at the user dashboard, and this is really just a file that inherits from
Administrate::BaseDashboard, which gives you some functionalities such as the field types. What we've got here is a list of all the attributes on the model, which is not necessarily in alphabetical order, I'm not entirely sure, but they seem to be mostly generated in the order that it looks like they were created, so they're probably the way you would expect, it looks like, the associations are at the top, though. Charges is an association we have, and this makes it into a
has_many fields, so administrate knows how to make form fields, and views for a
has_many type, which is cool. Then, it has the same thing for numbers, strings, datetimes and so on. You're also allowed to define your own field types, and we're going to talk about how to do that later on in this episode. You have the attribute types which is everything available, and then you can have your collection attributes, these are the one that show up on the index page here, so for episodes or index attributes or ID, title, description and created_at, and for users, it's their number of charges, the id, email and encrypted password, and you'll probably want to customize that, because you never really want to see the encrypted password, you just want to be able to change their password if you ever are an admin and need to do that.
Your show page is different, and every time you would click on one of these, you're going to get a view that is the more detailed version of that, and so for users, the index page can only show a couple of things, but when you click on one, it's going to show you a lot more stuff. As you can see, there's a little bit of CSS broken here, so there's work to be done in administrate, but you can also probably use this from their GitHub directly, and get more up-to-date fixes then using the gem, which will get published periodically. You can see that the charges association is actually generated a table of related charges, so that's pretty cool because it allows you to automatically say: This users has many of these, and then it will go on and embed them for you automatically. That is cool, I really like that, and the form attributes are the same deal. This really just says: The show page attribute should be everything, everything we've got, and it just grabs an array of keys that are available, and then the form attributes are not the same because we don't want to edit the user's database id for example, for that, we're going to set it to be a hard coded array, and we'll be able to change that. We can associate charges in there, but we can also edit these other things. This are all fields generally that we don't want to be able to edit, like the last sign in IP, and the current sign in IP, these devise fields, we don't want to be able to edit, but we would like to be able to edit their password. We can't just straight up change their encrypted password, we're going to need to build a custom field type for the password, so that we can do that, and it's really pretty straightforward how you can go about this. I'm going to go through comment these out, and we're going to have one for password, and password confirmation, which are the two fields that devise checks to see if they were submitted, and it will go ahead and update the user accordingly. We're going to use those fields to set the password and we're going to add a password here
password Field::Password. This is one that doesn't come with administrate and we're going to be able to edit this field, and so if we refresh this, it's going to break because we don't have the password field type yet, that's what we're going to take a look at, and that is going to be adding custom field types section here, so this is super easy. All you do is run a generator and it's going to generate a couple files. That is really all it does, so you can have a field file with some helper methods in it, and then you can also have your views, which are just little partials of how should this display on the index show and the form. Here we can run
railg g administrate:field Password This is going to make a few files and the main one is just going to add some helper classes or methods to a class if we ever need them, and then we have show and index and form views, so what that would look like in the show, in the index or in the form, because all of those will change a little bit. If we look at our password fields, really the two strings really just going to be the data, this is as if it was generating a string field, so we'll see that obviously we don't actually want to display the data if it ever gets printed out because it's a password, and we can comment that out, and then in your views folder, you have a new fields folder, and you'll have a password field folder there with the partials and so your form is going to just default to a text field, we can change this to the password field that we're looking for, and because this is a virtual attribute and it's a password that we never want to show, we can comment these out so that we never display any of the text that might have lingered around from the password. This brings us back to the user dashboard where we were kind of putting a placeholder in a field password, but all of the ones that start with field are coming from the gem, so this isn't actually what it generates, when you open up password field, you'll see that there's a class for a password field, and it's not
PasswordField so we're going to want to use
PasswordField here, instead. We can also add in the attribute of password confirmation with the same thing, these are the two devise virtual attributes that are used to set the password and the forms. We can add those down here to the form attributes, and those should now show up once we restart our rails server. Now if we go back to our rails app and click "Edit", we'll have a password and a password confirmation field, and that should allow us to say: Let's set a password to "test". Save that, and then if we go to localhost:3000 and we try to log in, "[email protected]" will have a new password of "testest" and should log us in, and it does. That is a nifty way of adding fields into your custom field types into your admin interface without having to do hardly any work. The beauty of this is that you can create the views and show them separately in each location. For example like those
has_many field types like a user
has_many :charges, there ends up being either the text of none, of if you go to a user that does have a charge like this one, you can see that it displays a table in the show action, but the index action it displays a pluralized number of charges. That's cool and you can basically expect out of their index one to just be a pluralized method, and then their show can be a little bit more complicated where it says: If there's some, then display a table with their attributes, and if not then we'll just display the text of non. This is pretty nifty and then also their form is going to be the edit and it will be the associated ones with an autocomplete link like this and all of that. So this is great, it allows you to really quickly generate new field types, which is always like a common thing in your applications, and then you have full access to these views if you want to go and customize them. That is another piece that we can grab, so we can go to the "Customizing page views" and here we can run
rails generate administrate:views., and this will generate all of the views for them. If we do that, you'll get the views admin applications, and everything in here will be customizable, so views/admin/applications/index.html.erb, you get all these little helpers, you get their content for the search, the header, it's all customizable to however you like it, and then I believe we also get access to and maybe not in this template here, but we should be able to give access to also customize the entire layout if we chose to. That might be something coming in the future, it doesn't look like this generates the layout, but that will be pretty great if it does as well. Then you can also customize the view for a specific resource. For example, if you want to do the views for users, then you can also get a scoped administrate users folder. What we just saw is this is the main applications one, so this is going to be the default views, and then the user's one would be overriding those specifically. This is cool. We can override however we would like this, so this is really flexible and there's still a bunch of little problems with this, for example right then when I generated these application views, editing any of these didn't actually work, and you'll see in the rails logs that if you viewed admin/users, it would just go ahead and render the templates from inside the gem here at the bottom. So it was rendering like the sidebar and all of this stuff was rendered from the gem instead of the application index that is in my example here. There's still some down sides with it, still some stuff that needs to get fixed and cleaned up, but this gem, I really like and think that it's worth checking out, it's definitely very rudimentary for the time being, but if you're interested in getting into open source and contributing to some gems like this, I would highly recommend it, this is also one that's new enough that it has a lot of little issues, for example like seeing that these application templates don't get loaded or used properly, that is probably a bug that is in their tracker right now that you can go and fix, so take a look at any of the open issues, maybe you have ideas of stuff that could be added, you could ask them for examples or guidance on how to implement it, I think they're doing a pretty darn good job of it, and I'm hoping to contribute myself to administrate in the future, and I just wanted to talk about this and mention it, because I think it's heading in the right direction and along the same though processes of what I was going to implement in my own admin gem.
Hope you enjoyed this episode and administrate saves you a bunch of time adding admins to your application in the future, and that's it for this episode, I will talk to you next week. Peace
I would not trust this with production data. It's much much much too early for anything more than a pet project.
Maybe, maybe not. It's definitely new but it's not much more than some basic scaffold generators right now. Nothing too special. I wouldn't use it on a client project yet, but I'd absolutely use it on personal projects.
I'm using ActiveAdmin for most sites since it existed beforehand, but now I'm starting to use Administrate in production. Only real concerns with this over production use is that it hasn't existed for all that long to work out the basic bugs. Since it's pretty much scaffolds, you can pretty easily debug anything that would go wrong. The main downside right now is going to be a potentially quickly changing API that may be more than you would want to deal with maintenance wise.
Ah that's disappointing. I wonder what the issue was with the JS...As long as you've got an easy admin to work with, that's all that matters.
really like the UI and simplicity of this Gem but yeah i think its too early to adopt..I couldn't find a command to remove all the files it has generated..is there any?
It's unlikely. Your version control system provides this.
Yeah, I don't know of _any_ generators that have an uninstall. Git works perfect for removing them though.
Yeah, I agree..was thinking of something like a 'destroy' command from rails..thanks for the video @excid3:disqus
Didnt find implementation for custom pages. Or there is nothing about this?
Hi Chris, Thanks very much for this overview. I'm trying to use this, except I'm running into a problem, which I think is related to have objects for which there is no controller.
I am currently getting this error:
NameError in Admin::Users#show
Showing /Users/mm/.rvm/gems/ruby-2.2.2/gems/administrate-0.1.3/app/views/fields/has_many/_show.html.erb where line #24 raised:
uninitialized constant Mailboxer::MessageDashboard
I think the problem might be that it can't make a space in the dashboard if there is no controller action. Do you have any ideas for how to solve this?
Thanks very much.
Also, if it helps others, if errors come up when you try to run the installer, try deleting the routes, running 'spring stop' in your terminal and re-running the installer.
To get your customized views to work move app/views/admin/applications to app/views/administrate/application. The generator does not copy files to the correct path.