題名が何いってるかわからんかもしれないのでどういうことか説明します。
ちょいちょいActiveRecord::Baseのattributeだけにメソッドを足してこういう風に書きたいことがあった。
html_snippet = HtmlSnippet.find(1) html_snippet.content = "Link to http://stackoverflow.com" html_snippet.content.replace_url_to_anchor_tag! # => "Link to http://stackoverflow.com"
これを実現するのにそのクラス定義内にcontentにreplace_url_to_anchor_tag!を追加するメソッドを定義したかった。
ActiveRecordのクラスはこんなかんじ
# app/models/html_snippet.rb class HtmlSnippet < ActiveRecord::Base # I expected this bit to do what I want but not class << @content def replace_url_to_anchor_tag! matching = self.match(/(https?:\/\/[\S]+)/) "#{matching[0]}" end end end
↑あきらかにClass classの@content(常にnil)にメソッドを定義してるため動かない。
1つの解;
頂いた回答によると、インスタンスメソッドの中で変数にメソッドを追加すればいい。ここでいうと`decorate_it`
class HtmlSnippet < ActiveRecord::Base # getter is overrided to extend behaviour of freshly loaded values def content value = read_attribute(:content) decorate_it(value) unless value.respond_to?(:replace_url_to_anchor_tag) value end def content=(value) dup_value = value.dup decorate_it(dup_value) write_attribute(:content, dup_value) end private def decorate_it(value) class << value def replace_url_to_anchor_tag # ... end end end end
なんかやりたいことに対してコーディング量がtoo muchじゃないかなとか思うんだけど、万が一もっと簡潔な方法があったら教えてください。