ドグサレ初心者のへっぽこビッグウェーブ

地球の底辺にいるゴミがプログラミングとか音楽とかを語るクソブログ

ちょいちょい見た目の手直しをする

fixtureでハイフン使うとエラーが起こる

$ rake db:fixtures:load
rake aborted!
ActiveRecord::Fixture::FormatError: a YAML error occurred parsing /Users/xx/xxxx/musico/test/fixtures/anime_details.yml. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html

どうやらエスケープしないといけないもよう。はい。
と言っても "" で囲むだけなんだけど。

タイトル一覧テーブルのページを追加

タイトルを一覧で削除するところがなかったので、scaffoldぽくテーブルを作って編集削除できるインデックスページを作る。

[aninme_title_controller.rb]

...
  # GET /anime_titles/titlelist
  def titlelist
    @anime_titles = AnimeTitle.all   #renderよりも先に書いておく
    render layout: 'applicationtitles'
  end
...

[titlelist.html.erb]
※ファイル作っただけなのでブランクページ。


ってコントローラとビュー作ってみたものの、ルーティングでエラー。
新しくアクションを追加する方法ってどうやるんだ。

アクション追加はルートを編集

techracho.bpsinc.jp

routes.rbでタイトルの中に一覧ページへのルートを指定するべし。
memberとcollectionの違いについては、

複数形はidなし、単数形はidあり」と同じ考え方で、「collection(集合)はidなし、member(個別)はidあり」と覚えましょう。

今回は一覧なのでid振ってページ複数作らない → collectionでよさそう。

[routes.rb]

  resources :anime_titles do
    resources :anime_details
    collection do
      get :titlelist
    end
  end
$ rake routes
...
       titlelist_anime_titles GET    /anime_titles/titlelist(.:format)                              anime_titles#titlelist
...

ルート作れました。

ページ内容

基本的にはanime_detail/indexのコピペ。
グリッドは多分おかしいけど、とりあえず表示できればいいので放置。

<div id="animetitlewrap" style="background-image: url(/assets/back.jpg);">
  <div class="container">
    <div class="row">
      <div class="col-lg-6 col-lg-offset-3">
        <h1>アニメタイトルリスト</h1>
        <h4>主に確認用</h4>
      </div>
    </div><! --/row -->
  </div> <!-- /container -->
</div><! --/headerwrap -->

<div class="container">
  <h1>Listing Anime Titles</h1>
  <p id="notice"><%= notice %></p>

  <div class="table-responsive">
    <table class="table table-striped table-bordered table-condensed newline">
      <thead>
      <tr>
        <!-- ヘッダ -->
        <th colspan="1"></th>
        <th class="col-xs-2 col-ms-2 col-md-2 col-lg-1">ID</th>
        <th class="col-xs-2 col-ms-2 col-md-2 col-lg-2">title</th>
        <th class="col-xs-2 col-ms-2 col-md-2 col-lg-3">icon_url</th>
        <th class="col-xs-1 col-ms-1 col-md-1 col-lg-1">icon</th>
        <th class="col-xs-2 col-ms-2 col-md-2 col-lg-2">created_at</th>
        <th class="col-xs-1 col-ms-1 col-md-1 col-lg-2">updated_at</th>
      </tr>
      </thead>

      <tbody>
      <% @anime_titles.each do |anime_title| %>
        <tr>
          <!-- anime_titleリスト %-->
          <td class="col-xs-1 col-ms-1 col-md-1 col-lg-1">
            <%= link_to '表示', action: :show, id: anime_title.id %><br>
            <%= link_to '編集', action: :edit, id: anime_title.id %><br>
            <%= link_to '削除', {action: :destroy, id: anime_title.id}, {method: :delete, data: {confirm: '削除してよろしいですか?'}} %>
          </td>
          <td class="col-xs-2 col-ms-2 col-md-2 col-lg-1"><%= anime_title.id %></td>
          <td class="col-xs-2 col-ms-2 col-md-2 col-lg-2"><%= anime_title.title %></td>
          <td class="col-xs-2 col-ms-2 col-md-2 col-lg-3"><%= anime_title.icon_url %></td>
          <td class="col-xs-1 col-ms-1 col-md-1 col-lg-1"><%= anime_title.icon %></td>
          <td class="col-xs-2 col-ms-2 col-md-2 col-lg-2"><%= anime_title.created_at %></td>
          <td class="col-xs-1 col-ms-1 col-md-1 col-lg-2"><%= anime_title.updated_at %></td>
        </tr>
      <% end %>
      </tbody>
    </table>
  </div>
</div>


<br>

<%= link_to 'New Anime Title', action: :new %>

<hr>
<%= link_to 'アニメタイトル一覧', anime_titles_path %>  |
<%= link_to 'トップへ', root_path %>

コントローラで自ら開けた穴にハマる

scaffoldで作ると作成されるprivateメソッドの「set_anime_title」が反応してエラー出てる。
「AnimeTitle.find(params[:id])」のidがねーぞ、って。ここ読まなくていいのになんで反応してるん。

と思ってたら

  before_action :set_anime_title, only: [:show, :edit, :update, :destroy, :titlelist]

自分で読み込むようにbefore_actionに追加してたってオチ。馬鹿か。

:titlelist消したら表示できました。めでたし。

タイトル一覧では最新のものから表示させる

現状はanime_titleのID順(DB入った順?)でゴリゴリ表示させてるんだけど、これを登録タイミング順にする。

って調べてみたけど、titlelistの場所でだけ、みたいに特定の場所で取り出し順序変える方法がわからぬ。

techracho.bpsinc.jp

どうせID順で使うことないし、とりあえずdefault_scopeを使ってモデル自体の取り出し順序を変える。

[models/anime_title.rb]

class AnimeTitle < ActiveRecord::Base
  has_many :anime_details, dependent: :destroy
  accepts_nested_attributes_for :anime_details
  default_scope { order("created_at DESC")}
end

DESCをつけることで、最新順になりました。

副次的にindexとかいろんなページのリストが最新順で表示された。

トップページは最新6件のみ表示する

今はrootであるhome#indexと、anime_titles#indexではほぼ同じ内容を表示している。
これをトップページでは件数制限をかけて、「もっと見る」とかで全部見れるようにしたい。

qa.atmarkit.co.jp

ループ指定は「.first(取得する個数)」をeach doに追加すれば頭から取ってこれる。カンタン。
「もっと見る」はとりあえずボタンを置いとけばいいや説。

んで、変更したものは_newestの部分テンプレートにして、_highlightから差し替え。

[ home/index.html.erb ]

<div id="headerwrap">
  <div class="container">
    <div class="row">
      <div class="col-lg-6 col-lg-offset-3">
        <h4>HELLO PEOPLE, MY NAME IS MUSICO!</h4>
        <h1>アニメのOPとEDをあつめるところ</h1>
        <h4>とりあえずつくってみた</h4>
      </div>
    </div><! --/row -->
  </div> <!-- /container -->
</div><! --/headerwrap -->

<section id="works"></section>
<div class="container">
  <div class="row centered mt mb">
    <h1>New entry Anime Titles</h1>
    <%= render partial: 'newest', locals: { anime_titles: @anime_titles } %>
  </div><! --/row -->
  <div class="row centered mb">
    <div>
      <%= link_to('タイトルをもっと見る', {controller: :anime_titles, action: :index}, :class => 'btn btn-default btn-lg' ) %>
    </div>
  </div>
</div><! --/container -->

[ home/_newest.html.erb ]

<!-- list 6 newest image -->
<ul>
  <% anime_titles.first(6).each do |anime_title| %>
    <div class="col-lg-4 col-md-4 col-sm-4 gallery backgroundbrink">
      <%= link_to({:controller => "anime_titles", :action => "show", :id => anime_title.id}) do %>
        <div style = "background: url(<%= anime_title.icon_url %>) 50% 20% no-repeat;
          background-size: cover; width: auto; height: 250px;">
          <div class="btn btn-success thumbbutton">
            <%= anime_title.title %>
          </div>
        </div>
      <% end %>
    </div>
  <% end %>
</ul>


なんとか形になりまっした。