Rails Tutorial 11章

11章のテストを書く演習
テストはむずいね
あからじめ3番目のユーザーはactivatedをfalseにしてある

testuser3:
  name: Test User3
  email: test3@example.com
  password_digest: <%= User.digest('password') %>
  activated: false
  activated_at: nil
  test "activated されたユーザーだけがuser/?として表示される" do
    log_in_as(@not_activated_user)
    assert_redirected_to root_url
  end

  test "activatedされたユーザーだけがusersに表示されるか" do
    log_in_as @user
    get users_path
    assert_select "a[href=?]", '/users/3', count: 0
  end

Multi Track Playerっぽいのつくった。

本人バレが怖いのでgithubのありかとか配備場所とかは言えませんが、私、バンド活動をしておりまして、練習後の会話で「マルチトラックレコーダーのweb版とか無いのかな?」という話になりまして、探したけど、きっとあるのだろうけど見つけられないので2時間ぐらいで作りました。作ったのはマルチトラックプレイヤーです。トラックをアップローダーでアップして、アップしたファイルをaudioタグにセットして協調して再生、一時停止、シークとかが出来ればよいかなと。バンドの皆さんからは高評価を頂いております。

アップローダーはいぜんどこからか持ってきたものを流用しました。以下、マルチトラックプレイヤー部分のソース。

phpファイル

<?php
error_reporting(E_ALL);

function getFiles(){
    $mp3_files = glob("/var/www/hoge/mtr/uploader/uploads/*.mp3");
    $m4a_files = glob("/var/www/hoge/mtr/uploader/uploads/*.m4a");
    return array_merge($mp3_files,$m4a_files);
}

function renderSelect($files,$i){
    $html = "<select id=\"select-" . $i . "\" style=\"display:inline-block\">\n";
    foreach($files as $k => $v){
        $html .= "<option value='" . normalizePath($v) . "'>" . basename($v) . "</option>\n";
    }
    $html .= "</select>\n";
    return $html;
}

function renderSetButtons($i){
    $html = "<button id=\"set-" .  $i . "\" data-select=\"select-" . $i . "\" data-audio=\"audio-" . $i . "\">set</button>\n";
    $html .= "<button id=\"unset-" . $i . "\" data-select=\"select-". $i . "\" data-audio=\"audio-" . $i . "\">unset</button>\n";
    $html .= "<span id=\"setted-" . $i . "\"></span>";
    return $html;
}

function normalizePath($value){
   return "https://somewhereinwww/hoge/mtr/uploader/uploads/" . basename($value);
}

$files = getFiles();
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="//code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<title>Multi Track Player</title>
<script src="//code.jquery.com/jquery-1.8.3.js"></script>
<script src="//code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<script src="app.js"></script>
</head>
<body>
<h1>Multi Track Player</h1>

<?php for($i=0,$l=8;$i <$l;$i++){ ?>
<div>
<audio id="audio-<?php echo $i?>" src="" controls>
  <p>音声を再生するには、audioタグをサポートしたブラウザが必要です。</p>
</audio>
<?php echo renderSelect($files,$i)?>
<?php echo renderSetButtons($i) ?>                       
</div>                                  

<?php } ?>
<p><button id="play">play</button>&nbsp;&nbsp;<button id="pause">Pause</button></p>
<div id="slider" style="margin:20px;"></div>
</body>
</html>

JS

$(function(){

  $("#slider").slider({min : 0});

  var max_duration = 0;

  function play(){
    $("audio[id^='audio']").each(function(){
      try{
        if($(this)[0].src != "" ){
          $(this)[0].play().catch(function(){});
        }
      } catch (x) { }
    });
  }
  
  function pause(){
    $("audio[id^='audio']").each(function(){
      try{
        if($(this)[0].src != "" ){
          $(this)[0].pause().catch(function(){});
        }
      } catch (x) { }
    });
  }
  
  function setCurrentTime(time){
    $("audio[id^='audio']").each(function(){
      if($(this)[0].src != undefined ){
        $(this)[0].currentTime = time;
      }
    });
  }
  
  $("#play").click(function(){
    play();
  });

  $("#pause").click(function(){
    pause();
  });

  $("button[id^='set']").click(function(){
    var src= $("#" + $(this).data("select")).val();
    $("#" + $(this).data("audio"))[0].src = src;

    setTimeout(function(elem){
      var duration = $("#" + $(elem).data("audio"))[0].duration;
      if(max_duration < duration){
        max_duration = duration;
        $("#slider").slider( {max : duration, min : 0 });
      }
    },200,this);
  });

  $("button[id^='unset']").click(function(){
    $("#" + $(this).data("audio")).attr("src","");
  });

  var players = $("audio[id^='audio']");
  players.each(function(){
    var player = $(this)[0];
    player.addEventListener("timeupdate",function(){
      if(player.currentTime){
        var VALUE = Math.floor(player.currentTime);
        $("#slider").slider({value : VALUE});
      }
    });
  });

  $("#slider").on("mouseup touchend",function () {
    var currentTime = $("#slider").slider("value");
    setCurrentTime(currentTime);
    play();
  });

  $("#slider").on("mousedown touchstart",function () {
    pause();
  });
});

chromeが怒るので

.catch(function(){})

みたいなソース初めて使いました。
jQueryから抜け出せない。
stackoverflow.com

Rails Tutorial 9章 10章

9章

なんかいつの間にか終わらせてた。
理解が進んでいないので一回読んだあともう一度読んだ。
自分一人で実装とかできる自信ない。

10.0の最初の演習

newとeditでformを共有したいって要件
下記のようにした。

view

optionで必要な値を与える

<% provide :title, "Sign up" %>
<% provide :button_text, "Create my account" %>
<% option = { url: signup_path } %>
<h1>Sign up</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= render "form", option: option %>    
  </div>
</div>

共有するform

<%= form_for(@user,  option ||= {} ) do |f| %>
  <%= render 'shared/error_messages' %>

  <%= f.label :name %>
  <%= f.text_field :name, class: 'form-control' %>

10.0の最後の演習

Nokogiriぇーー

    assert_select "div#error_explanation > ul > li", count: 4

面白いねrails。rails5は本当に完成度高い。

Rails Tutorial 8章

ruby2.4/rails5.0.1でやってる。当たり前でしょ.
Fixnum is deprecatedだよとか怒られながら。
途中ちょっとBcryptのとこで詰まったけどtypoだった。
ほかは引っかからずいけた。
gtagsもまだあんまり活用できてない。
anythingにgtags入れようかしら

Rails Tutorial 7章

特に引っかかるところもなく。
titleをprovide使わずに省力していたところをチュートリアルどおりに変更した。
guard良いね。
gtags苦心したけどあんま使わないな。今のところ。
rinariでうまいことやってる。

Emacsでgtagsと真剣に向き合い楽しくRails開発する2017

これまで

めちゃくちゃgrepしてた。もうやめたい。

やりたいこと。

  • タグジャンプがしたい
  • できればhelm/anythingで
  • タグファイルは自動更新してほしい

実行

gtagsのインストール

brew install global --with-exuberant-ctags --with-pygments

gtags.elはなんかパス通ってた

なければ
www.gnu.org
から落として展開してelみつけてパスの通ったディレクトリに置いて。githubとかで開発されてない。

anythin-gtagsのインストール

M-x auto-install-from-url [RET] https://www.emacswiki.org/emacs/download/anything-gtags.el

設定

(require 'gtags)
(require 'anything-gtags)
(add-hook 'ruby-mode-hook
          '(lambda()
             (gtags-mode 1)))

とりまruby-modeにフック

anythingの定義とかキーバインドとか

F3は定義ジャンプの定番(Eclipse教徒、信者ではない)

(defun anything-gtags-from-here ()
    (interactive)
    (anything
     :sources '(anything-c-source-imenu
                anything-c-source-gtags-select
                )
     :input (thing-at-point 'symbol)))
(global-set-key [f3] 'anything-gtags-from-here)

自動更新

;; update GTAGS
(defun update-gtags (&optional prefix)
  (interactive "P")
  (let ((rootdir (gtags-get-rootpath))
        (args (if prefix "-v" "-iv")))
    (when rootdir
      (let* ((default-directory rootdir)
             (buffer (get-buffer-create "*update GTAGS*")))
        (save-excursion
          (set-buffer buffer)
          (erase-buffer)
          (let ((result (shell-command "/usr/local/bin/gtags --gtagslabel=pygments")))
            (if (= 0 result)
                (message "GTAGS successfully updated.")
              (message "update GTAGS error with exit status %d" result))))))))

参考URLと違って生でshell-command叩いてる。特に深い意味はない。

プロジェクト初期作業

gtagsをプロジェクトルートで一回実行しておく

$ cd /path/to/project/
$ /usr/local/bin/gtags --gtagslabel=pygments

実際はaliasを設定しておけばよく、こんなコマンド覚える必要はない。

確認

メソッドがあるかどうかを確認するには global <メソッド名>

$ global new
app/controllers/users_controller.rb

*1

結果

ファイルを保存したらgtagsが走り、データベースが再生成される。メソッド呼び出しでF3押せばanythingで検索、ジャンプできる。M-*でジャンプ先から戻れる。
すごーい!
たのしー

*1:newメソッドはRailsプロジェクトなら多分あるよね。。。