内容一覧
Arrayのオブジェクトのpluckと、ActiveRecordオブジェクトのpluck
今までpluckはActiveRecordオブジェクトに対してしか使っていなかったが、Arrayに対しても使えることがわかった。
pry(main)> [{id: 1}, {id: 2}].pluck(:id)
=> [1, 2]
当たり前だがActiveRecordと違ってsqlが発行されない。
Brakeman
で指摘された以下のようなコードにて、Rails SQL InjectionのPluck Methodに記載の例の通りに試してみたが、うまくいかなかった。
# コード例
Mask.all.uniq.pluck(params[:target])
pry(main)> params = {}
pry(main)> params[:target] = "name FROM users--"
pry(main)> Mask.all.uniq.pluck(params[:target])
Mask Load (0.3ms) SELECT `masks`.* FROM `masks`
=> [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
uniq
があることによってArrayオブジェクトになっているからだとわかった。
pry(main)> Mask.all.uniq.class
Mask Load (0.5ms) SELECT `masks`.* FROM `masks`
=> Array
pry(main)> Mask.all.class
=> Mask::ActiveRecord_Relation
pry(main)> Mask.all.pluck(params[:target])
(0.4ms) SELECT name FROM users-- FROM `masks`
=> ["太郎", "一郎", "二郎". "三郎", "四郎", "五郎", .....]
ちなみにNon-attribute arguments will be disallowed in Rails 6.0
らしい。
pry(main)> Mask.all.pluck(params[:target])
DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s): "name FROM users--". Non-attribute arguments will be disallowed in Rails 6.0. This method should not be called with user-provided values, such as request parameters or model attributes. Known-safe values can be passed by wrapping them in Arel.sql(). (called from <main> at (pry):9)
vimのswapファイルとsshの接続
vimでファイルを編集のまま、保存せずにしばらく放置していたらssh接続が切れてしまったが、swapファイルから作業内容を復元。
今までswapファイルってなんか邪魔だなと思っていましたが、初めて役に立ちました。
というかそもそも一定時間で切れないように設定するべきではと思い、こちらの記事を参考に、.ssh/config
に以下を追記。
ServerAliveInterval 300
TCPKeepAlive yes
rails dbconsoleでパスワードを入力するのが面倒
以下で解決
$ rails dbconsole -p # rails db -p でもいける
Automatically provide the password from database.yml
https://github.com/rails/rails/blob/157920aead96865e3135f496c09ace607d5620dc/railties/lib/rails/commands/dbconsole/dbconsole_command.rb#L150-L151
下記の記事で見つけました。
https://teratail.com/questions/51709
https://qiita.com/taka0125/items/5d0d7cf58a9249ad0a96
メソッドの定義場所の探索
ちなみに、メソッドの定義場所を調べるのにsource_location
を使っていたけど、gemのpry
を入れると?
とか$
とかが使えるらしい。
https://qiita.com/jnchito/items/fc8a61b421d026a23ffe#comments
pry(main)> ? Rails::Generators::Base.class_option
From: /Users/knog/work/ruby_projects/rails_projects/sample/vendor/bundle/ruby/2.5.0/gems/railties-5.2.2/lib/rails/generators/base.rb @ line 202:
Owner: #<Class:Rails::Generators::Base>
Visibility: public
Signature: class_option(name, options=?)
Number of lines: 1
Make class option aware of Rails::Generators.options and Rails::Generators.aliases.
pry(main)> $ Rails::Generators::Base.class_option
From: /Users/knog/work/ruby_projects/rails_projects/sample/vendor/bundle/ruby/2.5.0/gems/railties-5.2.2/lib/rails/generators/base.rb @ line 203:
Owner: #<Class:Rails::Generators::Base>
Visibility: public
Number of lines: 6
def self.class_option(name, options = {}) #:nodoc:
options[:desc] = "Indicates when to generate #{name.to_s.humanize.downcase}" unless options.key?(:desc)
options[:aliases] = default_aliases_for_option(name, options)
options[:default] = default_value_for_option(name, options)
super(name, options)
end
最後のsuper
はどのクラスにあるのか疑問だったけど、試しに引数渡して実行してみたら、Thor
にあるっぽい。
pry(main)> Rails::Generators::Base.class_option(:hoge)
=> #<Thor::Option:0x00007f91585bd998
@aliases=[],
@banner="HOGE",
@check_default_type=nil,
@default=nil,
@description="Indicates when to generate hoge",
@enum=nil,
@hide=nil,
@human_name="hoge",
@lazy_default=nil,
@name="hoge",
@repeatable=false,
@required=false,
@type=:string>
Thor::Base::ClassMethods#class_option
def class_option(name, options = {})
build_option(name, options, class_options)
end
https://www.rubydoc.info/github/wycats/thor/Thor%2FBase%2FClassMethods:class_option
https://github.com/erikhuda/thor/blob/master/lib/thor/base.rb#L312-L314
build_option
は、
def build_option(name, options, scope) #:nodoc:
scope[name] = Thor::Option.new(name, {:check_default_type => check_default_type}.merge!(options))
end
https://github.com/erikhuda/thor/blob/master/lib/thor/base.rb#L590-L592