light log

学んだこととか

SQLite3の既存RailsアプリをMySQLに移行したメモ

今日書くことねーな。

じゃあ書かなければいいんだけど。

一応書く。

今日はSQLite3で作ってた既存RailsアプリをMySQLに移行したので、そのメモでも。

ながれ

  • Gemfileの編集
  • config/database.ymlの編集
  • MySQLのユーザを作成
  • rake db:create , rake db:migrate

これだけで動いた。

Gemfileの編集

+ gem 'mysql2'
-  gem 'sqlite3'

config/database.ymlの編集

新たにrails new appname -d mysqlで捨てアプリを生成して、そのdatabase.ymlをコピペした。

コピペした内容のusername, password, databaseを修正。

MySQLユーザの作成

↑で修正したdatabase.ymlのusername,passwordに従って、MySQLのユーザを作成。

よくわからないまま権限を与え過ぎてる気がするけど、development環境だからいいかな、という妥協。

rake db:create , rake db:migrate

見出し通り。

bin/rake db:create
bin/rake db:migrate

まとめ

意外とすんなり行った。

すんなり行ったせいでブログに書くことない。

本当は作成したMySQLユーザに与える権限とかもっと気にすべきなのかもしれない。 あと、:development環境と:test環境だけど、database.ymlにパスワード書いてるのも気になる。 参考にしたサイトだとあんまりその辺気にしてる感じのものがなかった。そういうものなのかな。。

参考

過去記事

yamacent.hatenablog.com

HomebrewでMySQLをセットアップしたらちょろりとハマった

ハマったのでメモる。

MySQLは昔に一回インストールしてあった(そのときもHomebrew)けど、どんな設定だったかとか何も覚えてないし、特に何にも使ってないので一回消してから入れ直すことにした。

環境

アンインストール

昔に入れたやつをアンインストールする。

$ sudo brew uninstall mysql
Password:
Uninstalling /usr/local/Cellar/mysql/5.6.24... (9719 files, 338M)
$ sudo rm -rf /usr/local/var/mysql/

参考:mac OS XにHomeBrewでmysqlインストール。からの設定(mysql_install_db、mysql_secure_installation、my.cnf)やらアンインストールやら - tweeeetyのぶろぐ的めも

インストール

再度インストールする。

参考:OSX - Mac へ MySQL を Homebrew でインストールする手順 - Qiita

$ brew install mysql

...

==> Pouring mysql-5.6.24.yosemite.bottle.tar.gz

...

そしたらこういうのが出てたので、

Warning: The post-install step did not complete successfully You can try again using brew postinstall mysql

言われた通りやる。

$ brew postinstall mysql

Error: Permission deniedになった。sudoをつける。

$ sudo brew postinstall mysql

うまくいった。

起動してみる。

$ mysql.server start
Starting MySQL
. ERROR! The server quit without updating PID file (/usr/local/var/mysql/mba.local.pid).

エラー。調べたらパーミッションっぽい。

[Mac]MySQLの導入 « 備忘録

しかしリンク先のように、

chown -R mysql:mysql /var/local/mysql

ユーザ名とグループ名を_mysqlにしても変わらず。

恐らく/usr/local/var/mysql/の上位ディレクトリがusername:adminってなってるからではないかと思って、

$ sudo chown -R username:admin /usr/local/var/mysql

としてみた。(usernameは適宜変える)

再度起動してみる。

$ mysql.server start
Starting MySQL
. SUCCESS! 

今度はうまくいった。

入る。

$ mysql -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.24 Homebrew

入れた。

セットアップ

上のリンクに従って以下をやる。

$ mysql_secure_installation 

対話的にセキュアな設定にしてくれる。

一応全部Yesにしたけど、ローカルで使う分にはrootのパスワード設定くらいでよかったかもしれない。

$ mysql -uroot -p

で、設定したパスワードを入力してログイン。

できた。

まとめ

これでまた使わず放置してると次回同じことになるかもしれないので、使おう。

will_paginateの出力をカスタマイズする

昨日↓の続き。今日も少し。

yamacent.hatenablog.com

トータル件数の上限を指定する

ページごとの件数上限指定は、昨日も書いた通り:per_pageを設定することで可能。

ただ、ページネーションしたいモデルの全件数が多い場合に、per_page: 20とかで表示するとページが何千ページとかに及んで邪魔だったので、最大ページ数を指定できないものかと思って調べた。

最初、モデルに対してlimit(100)として、その結果に対してpaginateすればいいかと思ったけどダメだった。全件表示される。

で、調べたら公式のAPI documentation(wiki)では見つからなかったけど、Stack Overflowで以下の回答が見つかった。

ruby on rails - Limit number of pages in will_paginate - Stack Overflow

回答によると、:total_entriesを指定する。

@posts = Post.order(created_at: :desc)
  .paginate(page: params[:page], per_page: 20, total_entries: 20 * 100)

:total_entriesで指定するのは最大ページ数じゃなくてトータル件数なので、「:per_pageで指定した件数 * ページ数」を指定する。(この例だと100ページ)

ただし、これで一応動いたものの、公式のドキュメントに記載が見つからないしStack Overflowの回答も結構古いものなので、使っていいものなのかいまいち自信がない。これが仮に非推奨だとしたら、これに相当する代替手段はあるはずだと思うんだけど。

表示のカスタマイズ

こっちはちゃんと公式ドキュメントに載ってたので安心。

  <%= will_paginate @posts, renderer: BootstrapPagination::Rails,
    previous_label: '&#8592; &nbsp;前', next_label: '次 &#8594;',
    inner_window: 1, outer_window: 0 %>
  • :previous_label - 前ページに戻るリンクのラベル
  • :next_label - 次ページへ進むリンクのラベル
  • :inner_window - 現在ページの周りに表示するリンク数 (default: 4)
  • :outer_window - 最初と最後のページの周りに表示するリンク数 (default: 1)

他にもあるので詳しくは公式ドキュメント参照。

まとめ

とても便利だけど、:total_entriesが気がかり。

過去記事

yamacent.hatenablog.com

yamacent.hatenablog.com

Railsでwill_paginateとwill_paginate-bootstrapを使った

今日は半日くらいSCSSを触ってた。floatの動きがいまいち感覚的に掴めない。

スタイルシートについては特に知見得てないので、今日は短いけどpaginationについて書く。will_paginateとwill_paginate-bootstrapで簡単しゃれおつページネーション。

環境

$ bin/bundle exec ruby -v
ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-darwin14]
$ bin/rails -v
Rails 4.2.1
$ bin/bundle show | grep -e "paginate" -e "bootstrap"
  * bootstrap-sass (3.3.4.1)
  * will_paginate (3.0.7)
  * will_paginate-bootstrap (1.0.1)

つかう

大体こういうのは簡単そうに見せかけて結局何かしらハマることが多いんだけど、今回は本当に簡単だった。

Rails Tutorialで一回やってるのも大きい。一箇所だけTutorial時点と使い方が変わっている部分があって一瞬あれってなったけど、公式のReadmeにちゃんと使い方書いてあったのですぐ解決できた。

ということで以下使い方。bootstrapは使える状態になってるの前提。

まずGemファイル。

gem 'bootstrap-sass'
gem 'will_paginate'
gem 'will_paginate-bootstrap'

バージョン指定してもいい(した方がいい?)

次にコントローラ。

@posts = Post.order(created_at: :desc).paginate(page: params[:page], per_page: 20)

order(...)の部分は適宜変える。per_pageの値もお好み。

次にビュー。ページネーションのUIを表示させたい場所に以下を挿入する。

<%= will_paginate @posts, renderer: BootstrapPagination::Rails %>

これのrenderer: ...の部分がRails Tutorialとは違って一瞬戸惑った箇所。

以上。簡単でびっくり。

まとめ

先人に頭が上がらない。

続き書いた

yamacent.hatenablog.com

過去記事

yamacent.hatenablog.com

yamacent.hatenablog.com

yamacent.hatenablog.com

iPhone6用のモバイルバッテリーを買う

大昔に買ったやつがバテてきてるので、新しく買おうと思って調べた。完全に自分用に調べたメモなので、汎用性ない。iPhone6を充電する想定。

途中からめんどくさくて割とどうでもよくなって、なんかすごく情弱っぽい買い物の仕方になった。いつもはもっとちゃんとしてるんだけどな。。

iPhone6のバッテリー容量

iPhone6の仕様には、

リチャージャブルリチウムイオンバッテリー内蔵

としか書いてない。以下の記事を見ると、

iFixitがiPhone 6/6 Plusを分解、バッテリ容量が判明 : ギズモード・ジャパン

1,810mAh

らしい。

求めるスペック

  • 値段:3k円台くらい
  • 容量:iPhone6を二回充電できたらいい
  • 出力:急速充電できるやつ
  • 重さ:そこまでこだわらない
  • 大きさ:そこまでこだわらない
  • デザイン:こだわらない
  • ポート:USB二個以上ほしい
  • 品質:安全そうなやつ

容量については、モバイルバッテリーでスマホを充電するときの効率が一般的に60%程度ってのをよく目にするので、iPhone6を二回満充電するためには、

1810 x 2 / 0.6 = 6033mAh

程度あればいいことになる。

安全性については以下の感じ。

決める

cheero社とAnker社がメジャーどころっぽい。面倒になってきたので、このどちらかでいいや。

どちらかというと、cheeroの方がデザインがかわいらしくて好感が持てる。でも上に書いた通り、デザインは別にそんなにこだわらない。

結構決めるのが難しい。当然容量が大きくなるにつれて容量あたりのコストは下がるようで、6000〜7000mAhくらいのものを買うなら10000mAh以上のものを買ってもそんなに値段変わらなかったり、バッテリー自体を充電するアダプタが付属しているものとしてないものがあったり。

例えば、これと、

これ。

上はちょうどいい容量で、下と比べて1000円くらい安いけど、アダプタが付いてない。下は付いてる。

で、アダプタは、

ちょうど1000円くらいする。

それだったら初めから容量でかい方のバッテリー買った方がいいよな。。

と思ったけど、やっぱり過剰な容量のものを買って不必要にでかく・重くなるのは嫌だ。

結局、決めかねてるのは上に書いた求めるスペックの「こだわらない」のせいなのだ。優先順位を付ける必要がある。持ち運ぶことを考えると、求める容量を満たすなら、サイズはできるだけ小さくて軽い方がいい。

ってことで上のやつにする。(した。)

これもすごく良さそうだと思ったけど、やはりでかい。

まとめ

なんかすごく疲れた。

結局メジャーなブランドの無難な商品を選んだけど、求めるスペックは全て満たす上に、値段は思ったより安かった。(きっと)いい買い物したと思う。

(おまけ)そもそもmAhって

mAh(ミリアンペアアワー)は、電池の容量を表す単位で、出力電流と放電しきるまでの時間の積。まぁ特に難しいこともなく直感的。

放電容量 - Wikipedia

Rubyのモジュールについて調べた

ちょっと前にモジュール関係で結構ハマって、なんでこれが動かないんだろうってのがあったので少し調べた。結局それはモジュール関係なくただの自分の(くそしょぼい)凡ミスのせいだったんだけど、せっかくちょっと調べたのでメモしておく。

はじめに

まずirbでこうやると、

$ irb
irb(main):001:0> Class.superclass
=> Module
irb(main):002:0> Module.superclass
=> Object

ModuleはClassのスーパークラスだとわかる。

つまり、ModuleはClassのもっと一般的なやつ。言い換えると、特殊なModuleがClass。

クラスとモジュールの違いは、リファレンスマニュアルを見ると、こう書かれてる。

クラスとモジュールには

  • クラスはインスタンスを作成できるが、モジュールはできない。
  • モジュールを他のモジュールやクラスにインクルードすることはできるが,クラスをインクルードすることはできない。

という違いがありますが、それ以外のほとんどの機能は Module から継 承されています。Module のメソッドのうち

  • Module#module_function
  • Module#extend_object
  • Module#append_features

は Class では未定義にされています。

class Class - Ruby 2.2.0 リファレンスマニュアル

以下の特性を見ると、モジュールはあくまでクラスの機能を補助(拡張)するものというイメージ。

  • モジュールはインスタンスを生成できない
  • モジュールは他のクラスやモジュールにincludeして使われる

一番シンプルな例。

module M
  def foo
    'module method'
  end
end

class C
  include M
end

puts C.new.foo
#=> module method

Rubyでのモジュールの役割

以下二つの役割がある。

Mix-in

クラスやモジュールにモジュールをインクルードすることをMix-inと呼ぶ。

Rubyのクラスは多重継承できないが、Mix-inなら複数のモジュールをインクルードすることができる。

module M1
  def foo
    'method foo'
  end
end

module M2
  def bar
    'method bar'
  end
end

class C
  include M1
  include M2
end

puts C.new.foo
puts C.new.bar
#=> method foo
#=> method bar

ずっとインクルードって書いてきたけど、モジュールを他のクラスやモジュールに取り込む機能としてはextendもある。

instance method Object#extend

モジュールのincludeが、指定したモジュールのインスタンスメソッドをクラス(やモジュール)のインスタンスメソッドとして追加するのに対し、extendはクラス(やモジュール)の特異メソッドとして追加する。

つまり、クラスにモジュールをextendすると、モジュールに定義されたメソッドをクラスメソッドとして使えるようになる。

module M1
  def foo
    'method foo'
  end
end

# モジュールにextend
module M2
  extend M1
end

# クラスにextend
class C
  extend M1
end

puts M2.foo
puts C.foo
#=> method foo
#=> method foo

名前空間

クラス定義をモジュールで囲むことで、名前空間として利用できる。異なる名前空間であれば、同名のクラスも定義できる。

module M1
  class Foo
    def foo
      'foo'
    end
  end
end

module M2
  class Foo
    def bar
      'bar'
    end
  end
end

puts M1::Foo.new.foo
puts M2::Foo.new.bar
#=> foo
#=> bar

その他もろもろ

以上が基本。当然もっと高度なトピックもある。

以下、調べてるときに出くわしたものの一部。さわりだけ。

クラスとの使いわけ

クラスAとクラスBに共通する機能を、クラスCにまとめて両クラスのスーパークラスとするのか、モジュールMにまとめて両クラスでインクルードするのかっていう判断は割と難しい(場合がある)と思う。たぶん、is-a関係とかhas-a関係とかを考慮に入れて判断するんだろう。

優先順位

インクルードしたモジュールにスーパークラスと同名のメソッドが定義されていた場合、モジュールが優先される。インクルードしたモジュールはサブクラスとスーパークラスの間に挟まれる継承関係になる。

module M1
  def foo
    'module foo'
  end
end

class A
  def foo
    'class foo'
  end
end

class B < A
  include M1
end

puts B.new.foo
#=> module foo

puts B.ancestors.join(' -> ')
#=> B -> M1 -> A -> Object -> Kernel -> BasicObject

複数のモジュールをインクルードした場合は、後でインクルードしたモジュールのメソッドが優先。

module M1
  def foo
    'M1 foo'
  end
end

module M2
  def foo
    'M2 foo'
  end
end

class A
  include M1
  include M2
end

puts A.new.foo
#=> M2 foo

instance method Module#include - Ruby 2.2.0 リファレンスマニュアル

module_function

メソッドをモジュール関数にします。

モジュール関数とは、プライベートメソッドであると同時に モジュールの特異メソッドでもあるようなメソッドです。 例えば Math モジュールのメソッドはすべてモジュール関数です。

class Module - Ruby 2.2.0 リファレンスマニュアル

module M1
  def foo
    'foo'
  end
  module_function :foo
end

class Foo
  include M1
end

puts M1.foo
#=> foo

# fooはプライベートになる
# puts Foo.new.foo
#=> private method `foo' called for #<Foo:0x007f844b087998> (NoMethodError)

まとめ

当面はこれだけの知識があれば大丈夫そう。わからないことがあったら都度調べればいいや。

参考

RubyのTwitter Gem使い方メモ(リスト周り) Part2

昨日↓の続き。少しだけ。

yamacent.hatenablog.com

リストに追加されている/リストを購読しているユーザの取得方法。

ユーザの取得は、リスト自体の取得に比べてRate Limitsの制限がゆるい。

require 'yaml'
require 'twitter'

CONFIG = YAML.load_file('config.yml')
client = Twitter::REST::Client.new(CONFIG)

user = 'yamacent'

# ユーザがメンバーに追加されているリスト (Twitter::Cursor)
memberships   = client.memberships(user, count: 10)

list = memberships.first

# リストのメンバー (Twitter::Cursor)
members = client.list_members(list.id, count: 1000)

# リストの購読者 (Twitter::Cursor)
subscribers = client.list_subscribers(list.id, count: 1000)

# subscribersでも同じ
members.each do |user|
  puts [
    user.id,              # ID
    user.screen_name,     # スクリーンネーム(@から始まるやつ)
    user.name,            # 名前
    user.description,     # 説明
    user.followers_count, # フォロワー数
    user.friends_count,   # フォロー数
    user.favorites_count, # お気に入り数
    user.lang,            # 言語
    user.location,        # 場所
                          # 他にもある
  ].join(', ')
end

参考

昨日といっしょ。