0

シンボリックリンクのように機能するレコードを追加できるようにしたい。言い換えれば、ほとんどの属性を別のレコード/オブジェクトに任せるレコード/オブジェクトを保存できるようにしたいと考えています。

シンボリックリンクが別のファイル (データを所有する) を指しているファイルシステムと同じですが、他のすべてを別のファイルに任せます。

class Document < ActiveRecord::Base
end

class Page < Document
end

class Folder < Document
end

class Symlink < ActiveRecord::Base
  set_table_name  :documents

  instance_methods.each { |m| undef_method m if (ActiveRecord::Base.instance_methods(false).include? m) && (!['link', 'link_id', 'link_id='].include? m) }

  def method_missing(sym, *args, &block)
    puts "Sending #{sym}(#{args.join(',')}) to obj"
    link.__send__(sym, *args, &block)
  end

  def save
    raise 'Symlink cant be saved' unless new_record?
    super
  end

  private

  def link
    @link ||= Document.find(self.link_id)
  end  
end

新しいレコードを作成しようとすると、「リンク」に対してスタック レベルが深すぎます。

これは、gem ( ) に抽出できる問題を解決するためのきちんとした方法だと思いましたacts_as_symlink :column => 'parent_id'

もう 1 つの考えは、元のレコードの完全なコピーを保持し、after_save コールバックを使用してシンボリック リンクを更新するか、シンボリック リンクが変更された場合は元を更新することでした。したがって、同期されたコピーのような実際のシンボリックリンクではありません。

私のコードまたは代替案について何か考えはありますか?

4

1 に答える 1

0

さて、私はそれをクラックしたようです。重要なのは、データベース列にアクセスするメソッドを、別のオブジェクトに延期するメソッドに置き換えることでした。idメソッドをsaveオーバーライドすることで、属性をシンボリックリンクまたは元のレコードのどちらに保存するかを決定することもできます。Document私の場合はacts_as_tree+acts_as_listなのでparent_idposition列を延期しないようにしているので、シンボリックリンクを別のフォルダーに割り当てて(他の方法では役に立たない)、そのフォルダー内に配置できます。

class Symlink < Document
  attr_accessor :save_to  


  self.columns.map { |c| c.name }.reject { |c| %w(position parent_id sync_id).include? c }.each do | col |
    self.send :define_method, col.to_sym do   
      source.send(col)
    end
  end

  def id
    if save_to == :symlink
      return read_attribute(:id)
    else
      return source.send :id
    end
  end

  def copy?
    !sync_id.nil?
  end


  private

  def source
    if sync_id
      @source ||= Document.find(sync_id)
    else
      Document.new
    end
  end
end

これまでのところコンソールでのみテストされていますが、これがフルスタックで機能しない理由。

それが成功した場合、私はこれを汎用のacts_as_symlinkgemに抽象化することを考えます。

于 2009-10-22T13:52:48.290 に答える