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
メソッドコメントの追加
/// (スラッシュを3つ)
上記を入力すると、以下のように展開されます。
/// <summary> /// /// </summary> /// <returns></returns>
これに適切なコメントを記述すると、パラメータヒントに表示されます。
メソッドを呼び出すときに表示されますので、しっかり記載しておいたほうが後々自分のため、チームのためになりますね。
クイックアクション (リファクタリングのアドバイス機能)
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 を使うことにしました。
時間ができた時に使ってみたいと思います。
ruby の eachメソッドでループ回数(インデックス)が必要な場合 (for文のiのような)
each するときに、ループ回数を利用したい
C言語とかで
for (i=0; i >10; i++) { ... }
とかやると思いますが、このループ変数 i を利用したい時がありますよね。
ruby だとどうするのがいいのか、わかっていなかったので調べてみました。
結果、rubyには便利なメソッドが用意されていました。
each_with_index
このメソッドはインデックスを振ってくれますので、これを利用して以下のように書けばうまくループ回数が利用できます。
tests.each_with_index do |test, i| puts "#{(i + 1)} : #{test.to_s}" end
=> 1 : test1 2 : test2 3 : test3 4 : test4 5 : test5
ここで、i+1 としているのは、インデックスは0から開始されるためです。
each.with_index()
じゃあ、インデックスの開始を指定できないの? ということで上記のように each に with_index() というメソッドをつなげると実現できます。
その場合、以下のように記載すればいいです。
tests.each.with_index(1) do |test, i| puts "#{i} : #{test.to_s}" end
fields_for の際に、インデックスを取得する
上記のような場面と似たような話で、Railsのform_forを利用している際に、更に fields_for を利用する場合、
= f.fields_for :test do |t| = t.index
とすると、インデックスを取得できます。
使い所はあまりないかもしれないですけど、ループさせるようなときには、意外と回数がほしいことがあるので、参考までに。
rails における enum型の注意点
当たり前の話なのかもしれませんが、rails アプリで enumを使用した際にハマったので、備忘として記載します。
前提
enum_helpをインストールしています
(試していませんが、enum_helpを導入していないと、そもそもviewでうまく呼び出せないとか)
参考 : ActiveRecord::Enum の使いドコロ - Qiita
enumはintegerで宣言すること
これ、stringで宣言してenum利用していたんですが、そうすると、登録は可能なんです。
でも、DBから取得する際にnilが返却されます。
しばらくの間なにが原因かわからなくて、時間を浪費してしまいました。
開発環境だったので、sqliteを利用していたのですが、sqliteの仕様かも、と疑ったりして。
なんのことはない、自分の宣言が正しくなかったという。。