日常

ケ・セラ・セラ

form submit ボタンにリンクっぽくfont awesomeを使う

メモです。

例えばこんな、fontawesome のハートマークをクリックしたら submit して likes/create or likes/destroy したいような状況ですが、

      <%= form_for(current_user.likes.build,
        html: { class: "form-inline" }) do |f| %>
        <div><%= hidden_field_tag :article_id, article.id %></div>
        <%= button_tag type: 'submit', class: "button-as_link" do %>
          <i class="fa fa-heart-o fa-lg c-like"></i>
        <% end %>
      <% end %>

font awesome を使いたくて、button をリンクのような見た目にしたかったのです。

こんな風に css を書いてそれっぽくなりました。(クラス名はちょっとひどいので後で整理しないといけない認識あります。。)

.button-as_link {
  background: none;
  border: none;
  padding: 0;
}

.form-inline {
  display: inline-block;
}

HerokuでRubyのバージョンを指定する

heroku に deploy したアプリがこけていて、なんだ?と思ったらぼっちオペレーターを使ったからだった。そういえば ruby のバージョン指定を忘れて 2.2.4 が使われていた。

やり方は、Gemfile に書けばよい。

source "https://rubygems.org"
ruby "2.3.1" # for heroku

現在の ruby のバージョンは以下のように見られる。

heroku run 'ruby -e "puts RUBY_VERSION"'

bundle install(with native extensions)に失敗する(Text file busy)

bundle install をすると、ことごとく with native extensions な gem が失敗するという状況に陥って困っていた。

こんなエラーメッセージが出ていて、

Text file busy @ unlink_internal - ./siteconf20160808-20166-29ij1u.rb

自分は virtual box の shared folder に指定したディレクトリ下で作業していたのだけど、どうやらそれが原因だったらしい。以下が参考になる。shared folder を避けて bundle install し直したら成功した。

最近の rails3.2 のはなし

ruby 2.3 から加わった Hash#to_proc がある。

この影響で、rails 3-2-stable ではこのような修正が merge された。これを含む 3.2系のリリースはまだされていない。

Associations do not call .to_proc on Hash #25043

4-2-stable にも master にもこのような変更が含まれていないのは、

そもそもこういった書き方は deprecated になっていて、

has_many :content_blocks, through: :page_blocks, autosave: true, source: :block, conditions: { page_blocks: { location: 'content' } }

こう書くようになっているから。という理解。

has_many :content_blocks, through: :page_blocks, autosave: true, source: :block, conditions: ->(*) { { page_blocks: { location: 'content' } } }

ここでまさに言っていたっぽい。

https://github.com/rails/rails/pull/23082

ひとこと加えておくと、好きで 3.2 を使い続けているわけではない。

ruby 2つのファイルを一行ずつ交互にマージしたい

ひとつめのファイル samplefile1

1
2
3
4
5
6
7
8
9

ふたつめのファイル samplefile2

one
two
three
four
five
six
seven
eight
nine
ten
eleven

とあった時に、こんな結果がほしい。という時。

1
one
2
two
3
three
4
four
5
five
6
six
7
seven
8
eight
9
nine
ten
eleven

こうしました。

今回は samplefile1.size < samplefile2.size な時に、samplefile2 の文字列だけ後ろに出力しておきたかったので、a2.zip(a1).map(&:reverse).flatten.compact のようにしました。

f1, f2 = %w(samplefile1 samplefile2)
a1 = File.readlines(f1)
a2 = File.readlines(f2)

a = if a1.size < a2.size
  a2.zip(a1).map(&:reverse).flatten.compact
else
  a1.zip(a2).flatten
end

File.open("outfile", "w") do |f|
  a.each {|s| f.write(s) }
end

もっと良いなにかがあれば知りたい。

YAMLファイルに別のYAMLファイルの値を参照、設定したい

こういうことがしたかったのですが、

# a.yml
id: 1
type: foo
description: baz

# b.yml
id: 2
type: bar
description: (ここで a.yml の description の値を参照したい)

こんな風にしました。

YAML.add_domain_type(nil, "include") do |type, val|
  YAML.load_file("path/to/a.yml")[val]
end

# b.yml
id: 2
type: bar
description: !include "description"

最初は b.yml.erb みたいにすればまあ出来るかなと、こんな感じのことを考えましたが、後で知った上の方法に変更したのでした。

# b.yml.erb
id: 2
type: bar
description: <%= YAML.load_file(path)["description"] %>

2016/08/05 追記

深い階層の場合にも対応しようと思い、こうしました。

# a.yml
id: 1
type: foo
description: baz
  too:
    deep:
      key: !include "深い階層にも対応"

# b.yml
id: 2
type: bar
description: (ここで a.yml の description の値を参照したい)
  too:
    deep:
      key: !include "too deep key"

# 今回は space 区切りを想定した。 うっかり space が多く含まれてしまった場合にも対応している。
      key: !include "  too                        deep           key     "

# YAML
YAML.add_domain_type(nil, "include") do |type, val|
  y = YAML.load_file("path/to/a.yml")["some_key"]
  val.to_s.strip.split(/\s+/).each do |key|
    y = y[key] unless y.nil?
  end
  y
end

# ruby 2.3 の場合は Hash#dig でこう書ける
YAML.add_domain_type(nil, "include") do |type, val|
  y = YAML.load_file("path/to/a.yml")["some_key"]
  y.dig(*(val.to_s.strip.split(/\s+/)))
end