rails 独学して軽くにちゃんまとめつくる

インターン中大学生のブログ

ぐるぐる回って何をしたいのかが変わってく。今はマッチングサイトを作りたい、もしくは論文のキュレーションサイトかな。

【rails】 モデルで最初から何個かとりだしたり、何番目から何番目を取り出す

User クラスの先頭から3番目までを取り出したいときはこうする

User.where(id: 1..3)

#SQL文  SELECT "users".* FROM "users" WHERE ("users"."id" BETWEEN ? AND ?)  [["id", 1], ["id", 3]]


[#<User:0x000000044cf410
  id: 1,
  name: "tarou tanaka",>,
 #<User:0x000000044cee20
  id: 2,
  name: "Foster Boyer",>,
 #<User:0x000000044cece0
  id: 3,
  name: "Miss Winnifred Jacobs">]

2点ドットを使えば連番を自動生成してくれるので上のコードは ID が1から3までのデータを収集してくれる。モデルの id は1から始まるので先頭を取り出したいときは 1 なので注意。

これを応用させて 2番目から5番目までを取り出してみると

User.where(id: 2..5)

とするそしたら2番目から5番目までがでてくる。

~応用例~

複数ある投稿記事きれいにレイアウトするときに使える。先頭とそれ以降のを切り分けて別のレイアウトにするとか。これは

f:id:mooooooooooriiiiii:20170415111609p:plain

  <% hajime_article = Article.first %>
  <div class="col-sm-12 thumbnail">
    <p><%= link_to image_tag(hajime_article.pic), hajime_article %></p>
    <div class="caption text-center">
      <h4><%= link_to hajime_article.title, hajime_article %></h4>
      <p><%= link_to hajime_article.site_name, hajime_article, class:"caption" %></p>
    </div>
  </div>
  <% Articles.where(id: 1..8).each do |article| %>
    <div class="col-sm-6 article" style="padding: 5px;">
      <span></span>
        <%= link_to image_tag(article.pic, class:"img-responsive"), article %>
        <div class="inner-article text-center">
          <h5><%= link_to article.title, article %></h5>
        </div>
    </div>   
  <% end %>

こんな感じで作っている。初めのとそれ以降のを別のレイアウトにすることによって見栄えよくさせているのである。

【rails】bootstrap の img-responsive を link_to(image_tag(), url) で使うときの注意点

bootstrap を使っていて画像を使いたいと気がくるだろう。そのときに img-responsive を使えば画像がレスポンシブ対応になってサイズを自動で変えてくれる。

rails で画像にリンクをつけたいときもくる。そういうとき

<%= link_to image_tag(pic), article %>

とするのだが、 img-responsive クラスを挿入するときは

<%= link_to image_tag(pic, class:"img-responsive"), article %>

としたらいい。img-responsive は img タグに直接つけなきゃならないから。

<%= link_to image_tag(pic), article, class:"img-responsive" %>

とすると、link_to のクラス名になってしまって img タグではなく a タグにくっついてしまうので注意。

【Bootstrap】 colいっぱいに画像を表示する

完成例はこんなやつ

f:id:mooooooooooriiiiii:20170414142127p:plain

失敗例はこんなやつ f:id:mooooooooooriiiiii:20170414142639p:plain

こんなのができる原因は bootstrap が勝手に padding を設定してしまうのが原因。よって padding をゼロにすればいい。

<div class="col-sm-6 t" style="padding:0; background-color:red;">
  <img src="http://photo-pot.com/wp/wp-content/uploads/2012/10/renga3_02.jpg">
  <div class="caption text-center">
    <h4>たいとる</h4>
    <p>だいめい</p>
  </div>
</div>

ポイントは col と同じ場所に padding を設定すること。自動挿入される padding は col によってなされているからだ。

bootstrap で "thumbnail" を使わないほうがいい理由

bootstrap ではブロックリンクをつくるときに thumbnail という便利なクラス名があります。これを使うと

f:id:mooooooooooriiiiii:20170414133240p:plain

こんな感じに四角形の中に写真やリンクをいれてきれいにまとめることができます。とくにインデックスページをつくるときに重宝します。もしこれでもいいやと思う人向けにこの html を書いておきます。

【コピペでそのまま利用可】

<div class="row">
    <div class="col-sm-6">
      <div class="thumbnail">
        <p class="img-responsive"><%= link_to image_tag(article.pic), article %></p>
        <div class="caption text-center">
          <a><h4>タイトル</h4></a>
          <p>サイト名</p>
          <p>ディスクリプション</p>
        </div>
      </div>      
    </div>
  
    <div class="col-sm-6">
      <div class="thumbnail">
        <p class="img-responsive"><%= link_to image_tag(article.pic), article %></p>
        <div class="caption text-center">
          <a><h4>タイトル</h4></a>
          <p>サイト名</p>
          <p>ディスクリプション</p>
        </div>
      </div>      
    </div> 
</div>

ただこれでは制限がいろいろとあります。 まず画像とテキストに左右のマージンができてしまいます。もちろん imge-responsive というクラス名を取り除いて自分で css で調整すればいいのでしょうが、それだと thumbnail をつかうメリットがありません。

つぎに文字の上下にできるマージンです。 p で文字を区切った場合こんな広さの空白ができてしまいます。だだっ広すぎてなんだか不格好になってしまいます。ブロックリンクに記述する情報量が2~3行である場合、ならthumbnail をつかってもいいかもしれませんが、複数行になる場合は使わないほうがいいでしょう。 f:id:mooooooooooriiiiii:20170414133240p:plain

col-sm-12 でかつ記述量がすくないときこうなる。

f:id:mooooooooooriiiiii:20170414134706p:plain

ボックスリンクの改行の場所でへんなズレが起こってしまいます。もちろんこれはボックスリンクの height を一定にすれば大丈夫なのですが、こうすることで先ほど説明したように文字の隙間がひろくなり不格好になってしまいます。

f:id:mooooooooooriiiiii:20170414134345p:plain

RailsTutorial のアクセス制御の correct_user の説明

rails tutorial でやった correct_user について説明する。

13章でやったようにマイクロポストを削除するときは current_user とマイクロポストの作者を比較して正しい場合のみ削除を実行するというものであった。結局やることはこれだけで、日本語にしたらわかるのだが、rails tutorial で書かれているコードはちょっとややこしいので改めて考えてみる。

リスト 13.52 をみてみると

  before_action :correct_user,   only: :destroy
・
・
・

    def correct_user
      @micropost = current_user.microposts.find_by(id: params[:id])
      redirect_to root_url if @micropost.nil?
    end

こんな風に書いてある。肝の部分は current_user.microposts.find_by(id: params[:id]) この箇所なのだがこれをどう理解したらいいだろう。

話を簡単にしてみよう。以下の話は rails tutorial のコードとは異なるので話を理解するだけでいい。結局比較したいことは自分(current_user) と micropost の著者が同じであることである。こんな風にユーザーとユーザーの比較したい。

f:id:mooooooooooriiiiii:20170414123352j:plain

だがアクセスしているリソースがマイクロポストであるため、マイクロポストからどうにかユーザーの情報を抽出したい。そうするためには user = Micropost.find(params[:id]).user_id とする。そしてこの user と current_user を比較することが、現在のユーザーとマイクロポストの著者を比較していることになる。だから correct_user を簡単に書き直すと請うなる。

def correct_user
  user = Micropost.find(params[:id].user_id)
  redirect_to root_url if current_user == user
end

f:id:mooooooooooriiiiii:20170414123540j:plain

だが tutorial では「current_userとマイクロポストのユーザー」というユーザー同士の比較ではなく、「current_userのマイクロポストとマイクロポスト」というマイクロポストの比較をしている。 図にすればこうなる。

f:id:mooooooooooriiiiii:20170414124456j:plain

current_user は複数のマイクロポストを持っている。その持っているものの中にいま削除しようとしているマイクロポストが含まれているか探している。まさにこのコードの日本語訳である @micropost = current_user.microposts.find_by(id: params[:id]) current__user.microposts で current_user の持っているすべてのマイクロポストを呼び出していて、 find_by(id: params[:id]) で削除しているマイクロポストが入っているかいなかを調べている。 その後もしなければ = (@micropost が nil) = current_user がそのマイクロポストを持っていなかったら root_path へ帰るようにしている。

ユーザーの比較でもマイクロポストの比較でも結局 current_user(図の左) と あるマイクロポスト(図の右)との比較であることに変わりはない。比較しているものは違っても結局していることは同じである。

bootstrap のリンクの色が変わらない

f:id:mooooooooooriiiiii:20170414095051p:plain

このようにリンクの色が黒くなったままの場合があります。 この例ではカルーセルの中にリンクをいれているのですが、黒くなったまま変わりません。 css で指定しても変わらないのですがこれはなぜでしょうか?

ブートストラップのリンクの状態というのが4つあるのが原因です。 ・通常バージョン ・未訪問バージョン ・訪問後のバージョン ・ホバー状態 です。

どうやらbootstrap では訪問済み状態にあるときリンクの色が黒っぽくなるようです。ということでここを css で変えるとよいので

a:visited 
    color:white;
    text-decoration:underline;
}

こうすればいいです。こうすれば

f:id:mooooooooooriiiiii:20170414095825p:plain

無事白くなります

【bootstrap】 thumbnail で間隔をあける

<div class="row">
  <div class="col-sm-6">
    <div class="thumbnail">
      <img src="https://www.textureking.com/content/img/stock/big/DSC_2685.JPG", class="img-responsive">
      <div class="caption text-center">
        <h3><%= link_to "click me!", class:"text-center" %></h3>
      </div>
    </div>      
  </div>  
  <div class="col-sm-6">
    <div class="thumbnail">
      <img src="https://www.textureking.com/content/img/stock/big/DSC_2685.JPG", class="img-responsive">
      <div class="caption text-center">
        <h3><%= link_to "click me!", class:"text-center" %></h3>
      </div>
    </div>      
  </div>  
</div>

こんな感じに <div class=“col-sm-6">~~</div\>の中に <div class="thumbnail">~~</div> をいれるとうまくいく。

f:id:mooooooooooriiiiii:20170413180010p:plain

ただ、こうした場合左右の隙間が見える。上は col-sm-12 で、下は col-sm-6 2つ分である。この方法は col と col の間には自動的に左右に隙間ができる性質を利用している。 CSS で直接 margin や padding で空白をつくろうとすると col の合計が 12 を超えてしまうため予期せぬレイアウト崩れとなってしまうので注意。

↓こんなかんじに

f:id:mooooooooooriiiiii:20170413173745p:plain