タグ別アーカイブ: Ruby

関西Ruby会議に行ってきた


話を聞いていたから、ほとんどメモはなかった。
すごいざっくりとした感じ。。
久々にこういう大きめのカンファレンスに出て、気持ち的なモチベーションは上がった!!

関西Ruby会議2017

フリーソフトウェア開発

Rubygem開発の流儀

‘何か考えて形にしてリリースする’ ということにハードルがある

  • 困っていることを正確に把握する
    • なんのせいで不便になっているのか
  • 開発に関わる手間が少ない方がいい
  • 運用コストが低い方がいい
  • 原動力
    • 日常の怒りや不満を言語化すること
    • 何がツライのかを説明できること
  • 引き出しを増やすこと
    • 頭のインデックスに引っ掛けるようにする
    • リファレンスマニュアル
    • 抽象化にはデザパタの知識は役に立つ
    • 既存のソースコードからパクる(ライセンスは確認)

CoderDojoを支えるRailsCMS活用事例

CMSのツールとしてよさそうだなぁー

18年でRubyから学んだこと

伽藍とバザール

フロントエンドの開発でファイルプロトコル(file://…)ではなくHttpプロトコル(http://)を使う


※ローカルにApacheを立ててバーチャルホストを作って云々という話ではありません。


背景

フロントエンドの開発において、htmlファイルをサクッとブラウザで開けば(file://…)、Javascript, css が動くというのはとてもメリットだと思うのですが、実際にサーバにアップロードしてアクセスするときにはほぼ100% Httpプロトコル(http://)でアクセスすると思います。そういった環境をローカル開発でも使うといいと思います。

file://hoge/fuga/index.html」などをブラウザ確認するとファイル内で imgタグ, scriptタグ, linkタグ などは以下のように 相対パス で書くことになると思うのですが、それをサーバにアップする時に 絶対パス に直すということをしている人は多いと思います。

<img src="img/hoge.png">
<link rel="stylesheet" href="css/hoge.css" />
<script src="js/hoge.js"></script>

その際、いちいち変換するのは面倒くさいので、pythonやrubyで動かせる簡易Webサーバを立ち上げてHttpプロトコル(http://…)で開発をしましょうという話です!

前提条件

  • Python or Rubyがインストールされているマシンを用意する(Macなら大丈夫。windowsはpythonとか入っていても起動できるかは謎)

  • ファイル構成

/tmp/workspace/
├── index.html
└── js/
    └── app.js
<html>
<head></head>
<body>
<h1>テストページ</h1>
<script src="/js/app.js"></script>     <!-- 絶対パスapp.jsを指定している -->
</body>
</html>

Pythonを使った例

ドキュメントルートとなるディレクトリへ移動する
$ cd /tmp/workspace

Webサーバを立ち上げる(3000はポート番号なので開いているPortなら何番でもOK)
$ python -m SimpleHTTPServer 3000

ブラウザを立ち上げて http://localhost:3000 へアクセスすると index.html が表示されます!

Rubyを使った例

ドキュメントルートとなるディレクトリへ移動する
$ cd /tmp/workspace

Webサーバを立ち上げる(3000はポート番号なので開いているPortなら何番でもOK)
$ ruby -run -e httpd . -p 3000

ブラウザを立ち上げて http://localhost:3000 へアクセスすると index.html が表示されます!

PHPを使った例

ドキュメントルートとなるディレクトリへ移動する
$ cd /tmp/workspace

Webサーバを立ち上げる(3000はポート番号なので開いているPortなら何番でもOK)
$ php -S localhost:3000

ブラウザを立ち上げて http://localhost:3000 へアクセスすると index.html が表示されます!

さらなるTips

Python、Rubyの場合は デフォルトの index.html がない状態でフォルダ指定してアクセスすると、DirectoryIndexが表示されファイルリストを見ることができます。
今回の場合は以下のように js フォルダにアクセスすると

http://localhost:3000/js

以下の様な画面が出力されます。(Rubyを使った場合)

Ruby-webrick-directoryindex

参考サイト

ワンライナーWebサーバを集めてみた -Qiita

[rails]Rakeタスクでのtask定義の「:environment」引数について


Railsのジェネレータで生成したタスクのrbファイルを見ているとRakeタスクを定義するところで少し疑問に思ったことがあった。

railsのジェネレーターで以下のとおりにタスクを作成する。

% rails generate TASK_FILE_NAME TASK_NAME

例)
% rails generate hoge test

例)のように実行すると lib/tasks/hoge.rb ができて testというタスクが定義される

namespace :hoge do
  desc "TODO"
  task test: :environment do
  end
end

タスク定義のところで「:environment」 という引数が渡されているが、どういうこのことなのかを調べてみた。

「RailsでオリジナルRakeタスク作成からRSpecテストまで」 の記事の中に以下の一文があったので実際に試してみる。

:environment は モデルにアクセスするのに必須

引用:RailsでオリジナルRakeタスク作成からRSpecテストまで


lib/tasks/hoge.rb を以下のように変更する。

(Userモデルのデータは別途用意していることが前提)

  1. testタスク :environmentの引数を渡さない
  2. test_twoタスク :environmentの引数を渡す
namespace :hoge do
  desc "does not huve environment args"
  task :test do
    puts User.first
  end

  desc "has environment args"
  task test_two: :environment do
    puts User.first
  end
end

それぞれを実行する

  • 1.testタスク :environmentの引数を渡さない
% rake hoge:test
rake aborted!
uninitialized constant User
…省略

=> なんか「uninitialized constant User」という例外でエラーになる。


  • 2.test_twoタスク :environmentの引数を渡す
% rake hoge:test_two
# <User:0x007fadd5f68a80>

=> ちゃんとユーザを取得できている

まとめ

RailsでRakeタスクを使ってActiveRecordのモデルなどを扱うときは 「:environment」引数を渡して上げると良い!

さらに、実行時にもenvironmentを呼ぶことが出来るようだ

rakeタスク実行時に environment をよんでから hoge:test を呼ぶ

% rake environment hoge:test

コードは読んでなく検証しただけなので、もっと詳しくは調べないとなー

Rails向けプリローダ spring1.0 で Rubygemsのバージョンアップが必要な件


rbenvでインストールしたrubyでRails向けプリローダのspringが1.0にメジャーアップしていたので、
使ってみたら、RubyGemsのバージョンが低いというWarningが出る。。。

Warning: You're using Rubygems 2.0.14 with Spring. Upgrade to at least Rubygems 2.1.0 and run `gem pristine --all` for better startup performance.
Version: 1.0.0

そこで、RubyGemsのアップデート方法を以下に書きます。(ずっとBundlerを使っていたので、急にRubyGems本体のアップデートとかやろうと思っても分からなかったので、、、)

アップデート手順

参考:
新しいgemのアップデート方法(rubygems-update)
本当有難うございます。まんまの手順でした。。

1.rubygems-updateをインストールする

% gem install rubygems-update

2.アップデート前確認

アップデート前にRubygemsのバージョンを確認しておく

% gem environment
RubyGems Environment:
  - RUBYGEMS VERSION: 2.0.14
  - RUBY VERSION: 2.0.0 (2013-11-22 patchlevel 353) [x86_64-darwin12.5.0]
省略

3.アップデート実行

% update_rubygems

4.アップデート後確認

% gem environment
RubyGems Environment:
  - RUBYGEMS VERSION: 2.1.11
  - RUBY VERSION: 2.0.0 (2013-11-22 patchlevel 353) [x86_64-darwin12.5.0]
省略

Rails3.2系でStrongParametersを有効にする方法


ゴール

Rails4系でデフォルトに組み込まれたStrongParameterをRails3.2系で使えるようにする。
Rails3.2系では3.1系から組み込まれた Model クラスに対して「attr_accessible」を定義することでMassAssignmentできるWhiteListの属性を指定しているが、この機能(attr_accessible)を無効化して、ControllerでparamsのWhiteListを指定するStrongParameterを利用できるようにさせる。


手順

(github README)strong_parametersについて

Ⅰ. モデルでのMassAssignment対策を無効

attr_accessibleの定義がなくても通るようになる

  1. config/application.rb 内 「config.active_record.whitelist_attributes」 を false にする
  2. Modelにあるattr_accessibleを削除
    attr_accessible があると config.active_record.whitelist_attributes の設定にかかわらずモデルでのMassAssignment対策が有効になる)

以上でモデルでのMassAssignment対策が無効化される( attr_accessible が無効)

Ⅱ. StrongParameters インストール

  • Gemfile に strong_parametersの定義を追加して bundle install
gem "strong_parameters"

Ⅲ. StrongParameters を有効にするための設定

これには今のところ2つの方法がある。適宜利用する方法を選択します。

1.各モデルに定義する

  • strong−parameter を有効にしたいModelに「include ActiveModel::ForbiddenAttributesProtection」を定義する
    メリット:各Modelごとに定義するので、Model毎で設定を入れるか入れないかを定義できる。
class AppVersion < ActiveRecord::Base
  include ActiveModel::ForbiddenAttributesProtection
  …省略
end

2.イニシャライザを新規作成して、そこに定義する

  • 独自のイニシャライザ (strong_parameter.rb)を作成して、その中に「ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)」の定義を入れる。
    メリット:一括で設定できるので全てのModelでStrongParametersを有効にしたいときは手間が省ける。
  # StrongParameterエラー時の挙動 :raise OR :log
  ActionController::Parameters.action_on_unpermitted_parameters = :raise
  
  # ActiveRecordの各ModelにStrongParameterをIncludeする
  ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)

以上で、通常のRailsコントトーラでStrongParametersを有効にする方法が完了です。
さらっと、2つ目のイニシャライザ作成のところで「ActionController::Parameters.action_on_unpermitted_parameters = :raise」 の設定を書いていますが、StrongParameters でUnpermittedParameters というExceptionが発生するときの挙動を定義しています。ここでは raise するようにします。


ActiveAdmin の対応

1.まずはコードから、、、

ここではデフォルトで作成される admin_userモデルについて書いています。

ActiveAdmin.register AdminUser do 
…省略

  controller do
    def permitted_params
      return {} if request.get?
      {admin_user: params.require(:admin_user)
        .permit(:email, :password, :password_confirmation)}
      # params.permit!     #<= 無条件にparamsを許可する場合
    end
end

■ コードの説明

  • 実装の概要
    controller do ブロックを作ってActiveAdminで採用されている inherited_resourcespermitted_params を定義して、paramsをpermitしたハッシュを返します。

  • return {} if request.get?」について
    HTTP Method の GETの時はぬけるようにして、新規作成(new) の時は除外する(GETの時はparamsにデータがないので)
    How to get ActiveAdmin to work with Strong Parameters?

  • params.permit!」について
    params を無条件ですべてpermitする場合に用いる、ここでは条件を指定してpermitさせている。

2.その他、Tips

[Tips1] Rails3.2系のActiveAdminでは admin_comment がStrongParametersに対応していないようです。

参考コード(active_admin/orm/active_record/comments.rb)
そのため、admin_commentって個人的には使わないし、以下のように無効にしています。

ActiveAdmin.setup do |config|
…省略
  config.allow_commetns = false
…省略
end

[Tips2] ActiveAdmin と言うか devise StrongParametersの対応方法についての参考情報

ActiveAdminでも採用されている 認証Gem devise では StrongParameters の対応方法にbefore_filterを使っているようです。