RailsでN+1問題
- N+1問題
一覧系画面を表示させる際、「全レコード取得 + 各レコードのデータ取得」分だけselect文を実行してしまう。的な問題。
例えばshopとmenuが1対Nの関係のDB構造のとき、以下のコードだと発生する
・sample_controller.rb
class SampleController < ApplicationController def index @menus = Menu.all end end
・sample.html.erb
<% menus.each do |menu| %> <p><%= menu.name %></p> <p><%= menu.shop.name %></p> <--ここでN回selectしてしまう <% end %>
- 解決策
最初にshop情報も一緒に取ってくる
・sample_controller.rb
class SampleController < ApplicationController def index @menus = Menu.includes(:shop).all end end
メモ
◇RailsでBootstrap sassを使う方法
1. Gemfileに以下を追加
gem 'sass-rails', '~> 5.0' gem 'coffee-rails', '~> 4.1.0' gem 'bootstrap-sass', '~> 3.3.5'
2. /app/assets/stylesheets/application.cssを「application.css.scss」にリネームし以下を追加
@import "bootstrap";
3. /app/assets/javascripts/application.jsに以下を追加
//= require bootstrap
4. このままだとスマホでレスポンシブルにならないのでapplication.html.erb内に以下を追加
<meta name="viewport" content="width=device-width, initial-scale=1">
◇link_toにBootstrapのbtnクラスを適用する
<%= link_to 'ボタン', test_index_path, class: 'btn btn-warning btn-block' %>
メソッド
// pタグの文字を赤字にする $('p').css('color','red'); // pタグのcssのcolorを取得する console.log($('p').css('color')); // pタグにmyStyleクラスを追加する $('p').addClass('myStyle');
- html属性やカスタム属性を操作・取得
- attr, data
// aタグのhref属性を取得 console.log($('a').attr('href')); // aタグのhref属性を設定 $('a').attr('href', 'http://google.co.jp'); // aタグのカスタム属性(data-sitename)を取得 console.log($('a').data('sitename'));
- タグの中身操作・取得
- text, html
- val
- remove(要素削除), empty
// pタグの値を設定 $('p').text('just changed'); // pタグのhtml要素を設定 $('p').html('<a href="">click me !</a>'); // inputタグの値を取得 console.log($('input').val()); // pタグの全ての子要素を削除し空にする $("p").empty();
- 要素を追加する
- before, after
- insertBefore, insertAfter
- prepend, append
- prependTo, appendTo
// ul直下でindexが1のli要素の前に、'just added'のli要素を追加する var li = $('<li>').text('just added'); $('ul > li:eq(1)').before(li); // 別の書き方 li.insertBefore($('ul > li:eq(1)')); // すべてのul要素の前にliを追加する $('ul').prepend(li); li.prependTo($('ul'));
- エフェクト
- hide, show
- fadeOut, fadeIn
- toggle
// idがboxの要素を隠す $('#box').hide(800); // idがboxの要素をフェードイン $('#box').fadeIn(800); // idがboxの要素をtoggle(あったら消す、なかったら出す) $('#box').toggle(800); // idがboxの要素をフェードアウトし、アラート出す $('#box').fadeOut(800, function(){ alert("done!"); });
- イベント
- click
- mouseover, mouseout, mousemove
// idがboxの要素をクリックした際alertを表示する $('#box').click(function(){ alert('click!!!'); }); // idがboxの要素に、、、 $('#box') // マウスオーバーしたら背景色を緑にする .mouseover(function(){ $(this).css('background','green'); }) // マウス離したら背景色を赤にする .mouseout(function(){ $(this).css('background','red'); }) // マウス動かしたらマウスのx座標を表示する .mousemove(function(e){ $(this).text(e.pageX); });
- formで使える
- focus, blur
- change
// idがnameのフォーム、、、 $('name') // フォーカスした場合、背景色を赤にする .focus(function(){ $(this).css('background','red'); }) // フォーカスを外した場合、背景色を白にする .blur(function(){ $(this).css('background','white'); }); // idがmembersの値が変わった場合アラートをあげる $('#members').change(function(){ alert('changed!!!'); });
- 動的に作られた要素の指定
- on
// buttonをクリックしたらvanishクラスを持つpタグを作成し、それをクリックしたら削除する $('button').click(function(){ var p = $('<p>').text('vanish!').addClass('vanish'); $(this).before(p); }); $('body').on('click', '.vanish', function(){ $(this).remove(); });
セレクタ
基本は$('要素')
- html要素(p h1 ul ...) ⇨ そのまま
【html部】 <p>jQueryの練習</p> 【jQuery部】 // p要素を赤文字にする $('p').css('color','red');
- id ⇨ #'id名'
【html部】 <p id="main">jQueryの練習</p> 【jQuery部】 // idがmainの要素を赤文字にする $('#main').css('color','red');
- class ⇨ .'class名'
【html部】 <p class="title">jQueryの練習</p> 【jQuery部】 // classがtitleの要素を赤文字にする $('.title').css('color','red');
- その他要素の指定
- > ⇨ 直下の子要素
- (空白) ⇨ それ以下の要素
- , ⇨ 複数の要素
- + ⇨ 隣接する要素
// main直下のitemクラスを赤字にする $('#main>.item').css('color','red'); // main以下の全itemクラスを赤字にする $('#main .item').css('color','red'); // p要素とitemクラスを赤字にする $('p, .item').css('color','red'); // itemクラスに隣接するitemクラスを赤字にする $('.item + .item').css('color','red');
// sub直下で2番目のli要素を赤字にする $('#sub>li:eq(2)').css('color','red'); // sub直下で2番目以降のli要素を赤字にする $('#sub>li:gt(1)').css('color','red'); // sub直下で偶数番目のli要素を赤字にする $('#sub>li:even').css('color','red'); // sub直下のli要素で値に2を含むものを赤字にする $('#sub>li:contains(2)').css('color','red'); // sub直下の最初のli要素を赤字にする $('#sub>li:first').css('color','red');
- メソッドを利用した要素指定
- parent(), children()
- next(), prev()
- siblings()
// subとsubの親要素を赤字にする $('#sub').parent().css('color','red'); // sub直下で2番目の次のli要素を赤字にする $('#sub > li:eq(2)').next().css('color','red'); // sub直下で2番目のli要素の兄弟要素を赤字にする $('#sub > li:eq(2)').siblings().css('color','red');
- 属性セレクタ
- =, !=, *=(〜を含む), ^=(〜で始まる), $=(〜で終わる)
// hrefが"http://google.com"の背景色を赤字にする $('a[href="http://google.com"]').css('background','red'); // hrefが"http://google.com"以外の背景色を赤字にする $('a[href="http://google.com"]').css('background','red');
*1:要素のindexは0から
setTimeout
setTimeout(関数,時間)
- 設定した時間(ms)を経過すると関数を呼び出す
- 関数は直接書いても、呼び出しでもOK(呼び出す場合はクォーテーションで囲む)
- 参考:http://www.pori2.net/js/timer/2.html