ダメでしょ!

プログラミングとか怒られた話とか…

simple_form を利用している時にsubmit ボタンにボタン名と value をセットする方法

前提

導入gem

普通の書き方だと、ボタン名が value の値になってしまう

通常、submit ボタンは以下のように記載すると思います。

= f.button :submit, 'ボタン名' { name: "#{f.object_name}[completed]", value: '1', class: 'btn btn-primary' }

しかし、この状態で実際に動作させてみると、ボタン名には value に指定した"1" が表示されてしまいます。
simple_form では、通常ボタン名が value にセットされますが、 value がセットされている場合はボタン名が反映されないためです。

こうすればうまくいく

では、どうすればいいのかというと、以下のように submit を指定せず、button を指定し、 do を付けてボタン名を入れ子にするとうまくいきます。

= f.button :button, { name: 'test', value: '1', class: 'btn btn-primary' } do
  ボタン名

simple_form 手強い...

simple_form を利用していない場合はハマらないと思うんですが、simple_form を導入していると最終的な html の出力が simple_form 次第になるので、ハマってしまった時に解決させるまでには試行錯誤が必要になることが多いです。。

simple_form と bootstrap を利用した環境で f.collection_select をどう書くか

前提

rails 4系
simple_form 3.2.1
bootstrap-sass 3.3.7

そのままだと(非bootstrap になる)

通常、collection_selectは以下のように記載しています。

= f.collection_select :option_id, OptionMaster.all, :id, :option_name, { prompt: true, class: 'form-control' }

しかし、これだと以下の画像のように、非bootstrapな表示をされてしまいます。 f:id:hideukin:20160822144011p:plain

bootstrap に対応した書き方

下のように記載することで、bootstrapに対応した表示になります。

= f.input :option_master_id, collection: OptionMaster.all.map { |v| [v.option_name, v.id] }

f:id:hideukin:20160822144109p:plain

f.input とした上で、collection: の後ろに配列で value と text の組を記載するのがポイントです。

公式も確認したのですが、いまいち曖昧に読み取れたので、ブログに書いてみました。

github.com

ruby において pry を利用している際に、binding.pry を強制的に停止する方法

ちょっと知らなかったので、小ネタですがご紹介。

pry を利用している場合、 ソースコード中に binding.pry と記載することで、記載した場所でデバッグが可能です。
これをループ中に利用し、どのように値が変わっていくかをチェックすることがあるのではないでしょうか。
そして、ある程度確認して、もうとりあえず停止したいけど、停止の仕方がわからない。。

こんな時には、コンソールに !!!と入力してください。

例外を発生させて、強制終了してくれます。

本当は以降の処理をそのまま流してくれるコマンドが知りたかったんだけど、そっちはわかりませんでした。
知っている人がいればぜひ教えて下さい。

ActiveRecord から取得した1レコードから配列を作成する

例として、option_mastersというテーブルが存在していた場合

#
# Table name: option_masters
#
#  id                 :integer          not null, primary key
#  option_name        :string
#  option1            :string
#  option2            :string
#  option3            :string
#  option4            :string
#  option5            :string
#  option6            :string
#  option7            :string
#  option8            :string
#  option9            :string
#  option10           :string
#  operator           :string
#  created_at         :datetime         not null
#  updated_at         :datetime         not null
#

このテーブルに登録されているはじめの1レコードを取得し、配列化したい場合は

OptionMaster.first.attributes.values

とすることで取得できます。
これはattributesでレコードをハッシュとして取得することができ、valuesでハッシュの値を配列として取得することができるためです。

今回は更に、テーブルに登録されているはじめの1レコードを取得し、option1~10 を取得したいとなりました。("option_name"や"operator"は値として必要なかった)
その場合、以下のように記載することで、目的を達することができました。

OptionMaster.first.attributes.select { |k, v| k =~ /option\d/ && v.present? }.values

これは、selectで条件に合致したキーの値だけを取得するためにk =~ /option\d/でキーに対して正規表現で記載しています。
更に、値が入っていない場合は必要なかったので、v.present?で除外しています。

まだまだこういったことがすぐにできるほど Ruby のメソッドを知らないので、作業速度が遅いですが、調べるたびに Ruby は書きやすいなぁと感じます。

Visual Studio でのリファクタリングに効果的な幾つかのショートカット

対象

Visual Studio 2015

Visual Studio には機能がたくさん

たくさんありすぎて、使い始めの人間には到底把握することができません。
使いこなすことができれば、生産性が格段に高くなるのでしょうが、学習コストも高いです。
自分が必要としていることを少しずつ調べながら覚えていきたいと思います。
そんな状態で、今よく使っている機能を紹介します。

対象のソースコードをメソッドとして切り出すショートカット

Crtl+R → Ctrl+M

f:id:hideukin:20160725175108g:plain

メソッドコメントの追加

/// (スラッシュを3つ)

上記を入力すると、以下のように展開されます。

/// <summary>
/// 
/// </summary>
/// <returns></returns>

f:id:hideukin:20160725175130g:plain

これに適切なコメントを記述すると、パラメータヒントに表示されます。
メソッドを呼び出すときに表示されますので、しっかり記載しておいたほうが後々自分のため、チームのためになりますね。

クイックアクション (リファクタリングのアドバイス機能)

Ctrl+.

選んだ行でいろいろなソースコード改善の提案をしてくれます。
例えば、数値の定数化や、不要なコードの削除であったり。
これは実際にやってみてもらうと良さがわかると思うのですが、言葉ではなかなかうまく説明できないです。。

リファクタリングに関する機能の追加

Visual Studio は2015バージョンで、リファクタリング関連の機能が増強されているようです。
昨今、ソースコードの改善がよく話題に上がりますが、その話題・要望にしっかりと応える形で機能を追加してきているみたいですね。
最近の Microsoft は非常に動きが早く、しっかりしているような印象があります。

C\# と Visual Studio による開発に着手

ほぼ初学者

仕事でC#のデスクトップ・アプリケーションに取り組まなくてはならなくなりました。
2年前くらいに1ヶ月ほど同じような仕事を行ったのですが、すでに遠い記憶の果て。。
ほぼ蓄積なし、一からの対応をしています。

C# のよさ

それはそれとして、C# はけっこう楽しかったりします。
学生の頃にJavaで研究課題を行っていたのですが、その当時はちんぷんかんぷんかつ、アプレットの実行速度も遅くて、全然楽しくなかった思い出があります。
C#Javaと記述が似ていますが、あの頃よりも楽しくコーディングできています。

Visual Studio

かなり高機能なIDEなのでしょうが、高機能すぎて全然使いこなせていません。
本当は Visual Studio にまず入門したほうが、効率もいいのでしょうね。
時間が限られているので、すっ飛ばして利用していますが。
今日は覚えられなくて何度か調べてしまったので、備忘として幾つか利用頻度の高いショートカットを記載しておきます。

リインデント(全体)

Ctrl+K → Ctrl+D

リインデント(指定範囲)

Ctrl+K → Ctrl+F

インテリセンスの再呼び出し

Alt+→(右矢印)
(Ctrl+space でもいいらしいのですが、自分は仮想環境で利用している関係上、うまく動きませんでした)

コメントアウト

Ctrl+K → Ctrl+C

コメント解除

Ctrl+K → Ctrl+U

デバック実行

F5

Visual Studio の既定のキーボード ショートカット

使い慣れていない言語に触れるということ

私が基本的に仕事で利用する言語は ruby です。
しかし、今回のように、案件によっては別の言語のほうが便利なときがあります。
実現したい内容による向き不向きというのは、当然言語によってありますので、切り替えが必要なわけなのですが、私のようにあまり経験が多くない人間にとって、別の言語と言うのはハードルが高いです。
ですが、メリットもかなりあって、別の言語に触れることで、よく利用する言語への理解が進む、ということがあります。
同じような書き方ができるところ、違う書き方になるところ、実現するためにはかなり書き込む必要があるところ(書き込まなくていいように言語がサポートしてくれている)など、違いを否応にも見せつけられるため、良さも悪さも見えてくる。
そんなふうに感じることができるのが、楽しいし、いいところだと思います。

rails でログイン認証されていない場合にログイン画面へ遷移させる方法(と、Active Admin を利用して管理画面を作成する際に除外する方法)

ログイン認証チェックを全画面に対応させる

./app/controllers/application_controller.rb に以下の様な形で認証チェックを入れます。

# ./app/controllers/application_controller.rb
class ApplicationController < ActionController::Base

  before_action :user_logged_in?

  def user_logged_in?
    if session[:user_id]
      begin
        @current_user = User.find_by(user_id: session[:user_id])
      rescue ActiveRecord::RecordNotFound
        reset_user_session
      end
    end
    return if @current_user
    # @current_userが取得できなかった場合はログイン画面にリダイレクト
    flash[:referer] = request.fullpath
    redirect_to login_index_path
  end
  
  def reset_user_session
    session[:user_id] = nil
    @current_user = nil
  end
end

まず、before_action :user_logged_in?の部分ですが、これでどのコントローラが呼び出された時でも、user_logged_in?メソッドが呼び出されることになります。
で、user_logged_in?では、認証情報の有無を確認することでログインしている場合とログインしていない場合の処理を分岐させます。
(上記の例ではsession[:user_id]を認証情報として利用しています。)

このままだと、ログイン画面でもこのチェックが行われてしまうため、ログインコントローラは除外する必要があります。
それは./app/controllers/login_controller.rbに以下のように追記します。(login_controller.rb は、名前はもちろん任意です。)

# ./app/controllers/login_controller.rb
class LoginController < ApplicationController
  skip_before_action :user_logged_in? <-この部分を追記
  ・・・
end

これにより、ログインコントローラ内では、認証チェックがスキップされます。

Active Admin で除外するには

で、今回、Active Admin という管理画面系のgemを利用したのですが、なにも考えずに導入したら、Active Admin が生成する管理者ログイン画面を表示する際にも、認証チェックが発生してしまって、利用者ログイン画面が表示されました。
これはまずいので、Active Admin 側では、ログイン画面と同じように認証チェックをスキップしたいと考えました。
application.rbに認証チェックを入れるのではなく、個々のコントローラに認証チェックを入れれば解決するのですが、それは今後コントローラが追加されることを考えるとうまい解決にはなりません。
で、結局どのようにするか。
ActiveAdmin にはコンフィグが用意されているのですが、このコンフィグ(./config/initializers/active_admin.rb)内に以下のように追加します。

# ./config/initializers/active_admin.rb
ActiveAdmin.setup do |config|
・・・
end

ActiveAdmin::BaseController.class_eval do
  skip_before_action :user_logged_in?
end

これで Active Admin 内では認証処理を行わなくなるため、 Active Admin 側の別の認証処理に認証を任せることができます。

[参考] 管理画面系gem administrate

今回の案件で管理画面が必要になり、改めて管理画面系の gem を探してみたところ、 administrate という gem が見た目シンプルでよさそうだったのですが、時間がなかったため今回は利用経験のあった Active Admin を使うことにしました。
時間ができた時に使ってみたいと思います。