20424


`lending_restricted`という名前の`boolean`のカラムを持つ`Company`というモデルがあるのですが、View
で以下のように`true`ならカラムと同名の`class`属性を追加しています。

[code]

    <tr class="company <%= 'lending_restricted' if company.lending_restricted? %>">
    
[/code]

これで動作は問題ないのですが、少し冗長な気がします。もっと良い書き方はありますか？

`Decorator`で少し抜き出そうかとも思ったのですが、あまり変わらない気がして…。


CC BY-SA 3.0
2015-12-27T16:47:37.150
20423
2015-12-27T21:32:08.160
3271
question
ruby-on-rails
booleanのカラムと同名のクラスをHTMLの要素に追加する方法


RubyやRailsのAPIで簡単に実現、っていうのは難しそうなので、ヘルパーメソッドを定義するのが落としどころになりそうです。  
たとえばこんなヘルパーメソッドを定義しておくと、モデルや対象の属性に関わらず汎用的に使えます。

[code]

    module ApplicationHelper
      def to_css_class(object, attr)
        attr.to_s if object.send(attr)
      end
    end
    
    <tr class="company <%= to_css_class company, :lending_restricted %>">
    
[/code]


CC BY-SA 3.0
2015-12-27T20:39:08.130
20424
2015-12-27T20:39:08.130
85
20423
answer


`Decorator`のことは知らないのですが、Decoratorパターン(みたいなのを)を使うくらいしかないような気がします。`Java`では`Interface`を使うのが普通ですが、`ruby`では直接それを表すのがないので、特異メソッドを利用するように実装してみました。

[code]

    def create_css_class_decorator(obj)
      obj.instance_eval{
        def classname_if_true(method_name)
          f = self.send(method_name.to_sym)
          affermative(method_name) if f == true
        end
    
        def affermative(s)
          s.gsub(/\?/,'')
        end
      }
      obj
    end
    
    (実行例)
    s = ""
    s = create_css_class_decorator(s)
    s.classname_if_true('empty?')
    => "empty"
    s = create_css_class_decorator("abc")
    s.classname_if_true('empty?')
    => nil
    # nil.to_s は空文字列が返ります
    
[/code]

上記の`create_css_class_decorator`メソッドを使って以下のように記述できます。メソッドの戻り値で得たオブジェクトは、メソッド実行前と同じオブジェクトです。２つメソッドが追加されただけで、それ以外は元通りに使い回せます。（…のはず）  
そこで質問の例にあるcompanyオブジェクトを事前に`create_css_class_decorator`で変換しておき、

[code]

    <tr class="company <%= company.classname_if_true('lending_restricted?') %>">
    
[/code]

とすれば上手く行くように思います。  
（例示のメソッド名は長いので適当に短い名前をつけるともっと楽かなとも思います）


CC BY-SA 3.0
2015-12-27T20:42:12.207
20425
2015-12-27T21:32:08.160
2015-12-27T21:32:08.160
9403
9403
20423
answer