Domains - aggregating all updates that have a given domain

Now we've reached a point where we'd like to offer a quick overview of all the content in a given domain. Since our Updates have a Domain field, we will start by displaying the recent updates that share the same domain.

How should we proceed?

Let's go back to the Rails diagram:

To see all content related to a domain, we'd like our users to go to a page like casemanagementsystem.md/domains/social or localhost:3000/domains/education.

Generally, all content from a given domain will be located at localhost:3000/domains/domain_type. These pages will be accessible to authenticated users.

Under this premise, open the file config/routes.rb and edit the block:

authenticated :user do
  root to: "cases#index", as: :authenticated_root
end

to include:

authenticated :user do
  root to: "cases#index", as: :authenticated_root
  get "domains/:domain_type" => "domains#filter", as: :domain_filter
end

In the line above, domains/:domain_type is able to resolve all links of the form domains/anytextgoeshere with the aid of the action filter in the domains controller. anytextgoeshere will be passed as the domain_type parameter to the filter action. The path associated with this series of links is thus called domain_filter_path.

Controller and action

Save the file, open the browser and try to visit a page, let's say localhost:3000/domains/social.

You will get the following error:

The error states that there is no DomainsController. Let's create one.

Create a new file, app/controllers/domains_controller.rb type in the following, then save the file:

class DomainsController < ApplicationController
end

Refresh the browser:

A new error! There is no filter action in the DomainsController. We need to add one.

We would like the filter action to return all the updates for which the domain is the same as the domain_type the filter action receives as a parameter. We will write this programmatically like this:

class DomainsController < ApplicationController

  def filter
    @updates = Update.where({:domain => params[:domain_type]})
  end
end

View

Save the file, refresh.

A new error, this time - missing template. We know we need to create a view.

Create the app/views/domains folder and the app/views/domains/filter.html.erb file, write anything in it, save the file and refresh the page:

Phew! It works. We only have to make it work properly.

Rendering the updates

We now know that the filter action creates an instance variable @updates that has all the updates form the domain_type we passed as parameter.

In the previous chapter, we also carefully prepared a partial we can use when we want to render this collection.

What follows is both straightforward and magic. Edit the app/views/domains/filter.html.erb file to include the following:

<div class="container">
  <h3>Updates</h3>
  <%= render :partial => "updates/update_with_case", :collection => @updates, as: :u %>
</div>

Save the file and refresh the browser page:

Oh wow! It worked!

Refinements

Edit the app/views/domains/filter.html.erb to add the internal navbar and the domain name:

<%= render "shared/internal_navbar" %>

<div class="container">
  <h2><%= params[:domain_type] %></h2>

  <h3>Recent updates</h3>
  <%= render :partial => "updates/update_with_case", :collection => @updates, as: :u %>
</div>

Since our service may be very-very good and popular, we'd like to show only the most recent, let's say 200 updates from a given domain. For this, in the DomainsController, change the filter action to:

def filter
  @updates = Update.where({:domain => params[:domain_type]}).order(id: :desc).limit(200)
end

Refresh the page:

Beautiful.

Linking to the domain page

Now that we have the domain page, let's make the labels on the updates act as links to the page. To do this, and thanks to the preparations in the previous chapter, we will have to edit only two partials.

Open the file app/views/updates/_update.html.erb and change the following line:

<span class="label label-primary"><%= u.domain %></span>

to

<span class="label label-primary"><%= link_to(u.domain, domain_filter_path(u.domain), style: "color: white") %></span>

Open the file app/views/updates/_update_with_case.html.erb and change the line:

<span class="label label-primary"><%= u.domain %></span>

to

<span class="label label-primary"><%= link_to(u.domain, domain_filter_path(u.domain), style: "color: white") %></span>

You have already recognized the use of the link_to helper and the inline style for white color of the text.

Restricting the domain selection

Right now, the users can post updates from virtually any domain. Since the applications have restricted use, we would like them to be able to select, not type, one of the pre-defined domains.

The component that helps us achive this is a select - you can find a sample in the Rails Boostrap Forms gem documentation.

Open the app/views/cases/show.html.erb file, locate the code that renders the Post a new update form.

Next, we will have to replace the line:

<%= form.text_field :domain, label: "Domain", required: true %>

with the following:

<% possible_domains = [["Social", "social"], ["Financial", "financial"], ["Education", "education"]] %>

<%= form.select :domain, possible_domains, label: "Domain", required: true %>

What we did is create a variable, possible_domains, that contains a list of domains and the labels used to display them. Next, we are using a select helper that will show the user the possible_domains she can choose from when she creates an update.

This is how it looks like in use:

results matching ""

    No results matching ""