Building a Scope to Show the Most Recent Blog Posts and Hiding Drafts from Non Admins
It's important to understand how to securely show and hide posts from users. In this guide we'll walk through how to use custom scopes to hide draft posts blog posts from non admin users. We'll also examine how we can leverage the status enum to easily call draft and published blog posts.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

If you followed along and took each one of these items and built them out. Congratulations and very nice work. In the next few guides and it is going to take a number of them. We are going to walk through what my own personal take on the solutions are. I do not pretend to say that these are the only or even the best solutions. They're simply what I personally would do if given the set of tasks.

I'm going to click and drag this into our current backlog. Pop it open and let's press start. Scrolling down we can see we have all kinds of tasks and one of the most intimidating things that a developer can face is a list that looks something like this. Don't let it scare you away. I think that we can compile some of these put them together and you'll see some of these are actually already live. We simply need to be able to update them and to integrate them. For example, the first one that I want to tackle is the recent scope for blogs. This is something that technically we already have access to because of our blog enum. Let's take a quick look at this. First, switch over and say git checkout -b final-changes, for the branch. I'm going to open up the Rails console. One thing that I can do because of our enum is I can say blog.published or blog.draft and we already have a scope. Let's see exactly, as soon as the Rails console decides to open up then we can say Blog.published. That shows that we have no items that are published andBlog.draft. This shows that all of them are in draft mode so lets first do a couple of things. I'm going to start up the Rails server and let's switch into the browser and actually go take a look at our actual data. First, we have to make sure we're logged in and I am. Let's update the status of a few of these. I'm going to say update this one, this one, and this one. Remember that was our action or custom action that goes and changes the status from draft into publish so now we'll have three published ones. If you want to confirm that, you can come here and we can start up a terminal session and run the exact same commands except now when we say published you can see we have three and draft brings up a ton of them. That is good. Let's see what we need to do in order to implement this behavior. Ideally what we want is for our published post to be shown to everyone and our draft and our other ones. So, draft and published to be shown to us or to admin users. Switching over into this I'm going to go into the blogs_controller.rb and in our index action, this is where we can come and hide our items, or the ones that we want to hide. When we say blogs and right now we're just saying This is essentially the same as saying blog.all which is the reason why everyone can see them. What we want to do is to change this up just a little bit. This is what we want for us to see. But what we want for other users to see is only blog.published and then the rest of it. Let's see how we can update this. I think one of the easiest ways is just to use our 'petergate' method so I can say...

def index
  if logged_in?(:site_admin)
    @blogs =[:page]).per(5)
    @blogs =[:page]).per(5)
  @page_title = "My Portfolio Blog"

if then logged_in?(:site admin) then we can assign the blogs instance variable to that and say else we're going to assign the blog instance variable to and this is going to hide the draft one. If I hit save and come back to the site nothing should change. This should all still work exactly like before but now if I hit logout and come back to the blogs. Now we should only see published blog posts which is exactly the behavior that we want. This is perfect! We still have something that is a little bit of a problem and it's connected. So, I think this would be a good time to implement it especially because that feature really didn't take us that long to build out. Let's log back in and let's create a new blog post. I'm going to just create a basic one here hit submit. This is created. But now if we come back to the blog you can see that even though that was our newest post it is not the first one shown. In fact, it is the very last one that is shown. I'm going to one change up this so it's published but then also let's go change our scope here. Let's go here and now we have our published and we have our regular. But what we can do is go to blog.rb and create a new scope. You can see we have these sample ones we walked through. Let's kind of mimic that and I'm going to say...

def self.recent
  order("created_at DESC")

def self.recent and here all we have to say is order. Then for this one it's going to be created_at descending(DESC). Now, inside of this(blogs_controller.rb) we can just call blog and right after published or right here we can say recent. and this should give us exactly what we are wanting...


If I hit refresh. Now this is perfect so now it shows the very latest post at the top. Even if I make a change such as changing this to published now it does not move it to the end of the line the way it did before. Let's also verify that this is working here for non-logged in users. As you can see the scope is working perfectly. This is exactly the behavior that we want.

Let's close this off say, git status, git add . and for our commit message say "Implemented custom scope for recent blogs and hide draft posts from non admins". That's perfect. Now git push origin final-changes. That'll all get pushed up and now if I come to pivotal tracker. We can see that we updated the recent scope for blogs and then let's see what else so, blog status update, no. Skills for about, no. ok, there we go Update blog scope so only admin users can see draft posts. This is perfect. Ok we knocked out two in one guide. Great job going through that. In the next section we're going to start walking through the build-out of our topic.