SamuraiBlue
SamuraiBlue

Reputation: 861

Rails4: How to display the value one time only

I'd like to display the room name for one time only. Summarized as follows;

articles table

id day start_time title
2  1   09:00      Math
4  2   10:00      English
5  1   11:00      Science
8  3   12:00      Physics
9  2   13:00      Music

rooms table

id day name
3  1   classA
6  2   classB
7  3   classC

I'd like to display the data in the view as followings;

Day1
09:00 Math
11:00 Science
Room classA

Day2
10:00 English
13:00 Music
Room classB

Please advise me on how to display the value as above. The room names are displayed each time in the code below.

View code

<div class="row">
  <% @article.group_by(&:day).each do |day, articles| %>
    <h3>Day <%= day %></h3>

    <% articles.each do |a| %>
      <%= a.start_time %>
      <% a.category %>
      <%= a.contents %><br>
      <%= a.matching_detail.try(:name) %><br> #I'd like to display only one time
    <% end %>

  <% end %>
</div>

Model code

class Article < ActiveRecord::Base
    belongs_to :school
    has_many :rooms, through: :school
    default_scope -> { order(day: :asc, start_time: :asc) }

    def matching_detail
      rooms.find_by_day day
    end
end

class Room < ActiveRecord::Base
    belongs_to :school
    belongs_to :article
end

Schema

ActiveRecord::Schema.define(version: 20150999999999) do

  create_table "rooms", force: true do |t|
    t.integer  "school_id"
    t.integer  "day"
    t.string   "name"
    t.string   "detail"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "articles", force: true do |t|
    t.integer  "school_id"
    t.integer  "day"
    t.string   "start_time"
    t.string   "end_time"
    t.integer  "category"
    t.string   "title"
    t.string   "contents"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "schools", force: true do |t|
    t.string   "title"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

end

Upvotes: 1

Views: 302

Answers (2)

alexanderbird
alexanderbird

Reputation: 4198

I recreated your rails project by:

  1. rails new SchoolScheduler
  2. added schema file from your question
  3. rails db:schema:load
  4. added your model files - Article and Room
  5. added your test data in db/seeds.rb to populate the database (see below)

Then I made some changes:

  1. added a scaffold for schools: rails g scaffold School title:string (had to delete the migration file that was added to db/migrate)
  2. updated the school model (see below)
  3. updated the school view (show.html.erb, see below)

Then I tested it out:

  1. Fired up rails s
  2. navigated to http://localhost:3000/schools
  3. Clicked on "Show" for "The One You Want To Show"
  4. Voila!

Screenshot of final view

db/seeds.rb

School.delete_all

School.create(id: 1, title: "The One You Want To Show")
School.create(id: 2, title: "Some Other School")

Article.delete_all

Article.create(id: 2, school_id: 1, day: 1, start_time: "09:00", title: "Math")
Article.create(id: 4, school_id: 1, day: 2, start_time: "10:00", title: "English")
Article.create(id: 5, school_id: 1, day: 1, start_time: "11:00", title: "Science")
Article.create(id: 8, school_id: 2, day: 3, start_time: "12:00", title: "Physics")
Article.create(id: 9, school_id: 1, day: 2, start_time: "13:00", title: "Music")

Room.delete_all

Room.create(id: 3, school_id: 1, day: 1, name: "classA")
Room.create(id: 6, school_id: 1, day: 2, name: "classB")
Room.create(id: 7, school_id: 2, day: 3, name: "classC")

app/models/school.rb

class School < ActiveRecord::Base
  has_many :rooms
  has_many :articles

  def days
    self.articles.pluck(:day).uniq
  end
end

app/views/school/show.html.erb

<p id="notice"><%= notice %></p>

<p> 
  <strong>Title:</strong>
  <%= @school.title %>
</p>

<% @school.days.each do |d| %>

  <h3>Day<%= d %></h3>

  <% @school.articles.where(day: d).each do |a| %>
    <%= a.start_time %>
    <%= a.title %><br>
  <% end %>

  <p>Room <%= @school.rooms.where(day: d).first.name %></p>  

<% end %>

</br>
<%= link_to 'Edit', edit_school_path(@school) %> |
<%= link_to 'Back', schools_path %>

If I were you, I might refactor the #where.(day: d)... from the view into the model, but that's minor.

As an afterthought, you can simplify your Article and Room models from what you have in your question to this:

class Article < ActiveRecord::Base
  belongs_to :school
end

class Room < ActiveRecord::Base
  belongs_to :school
end

Upvotes: 2

akbarbin
akbarbin

Reputation: 5105

I would try to help to:

Controller

In this section, you need to select field that you need only. Then, join articles table with rooms.

@articles = Article.select("articles.id, articles.title, articles.contents, articles.category, articles.created_at, rooms.name AS room_name").joins(:rooms).group_by{|x| [x.created_at, x.room_name]}

Model

Remove matching_detail method because you don't need this method. It's method will load data in looping so I will be long to load your data.

View

For view, you have to edit some codes so it can be showed below.

<div class="row">
  <% @articles.each do |data, articles| %>
    <h3>Day <%= data[0] %></h3>
    <% articles.each do |a| %>
      <%= a.start_time %>
      <% a.category %>
      <%= a.contents %><br>
    <% end %>
    <%= data[1] %><br> #I'd like to display only one time
  <% end %>
</div>

Notes: data[0] is for day and data[1] is for room name I hope this help you.

Upvotes: 1

Related Questions