0

ノードと呼ばれるモデルでacts_as_nested_setを使用しています。データベースには複数のリストが保存されており、それぞれがルートノードから始まります。ルートノードには親がありません。これがルートであることを私が知っている方法です。

これですべて期待どおりに機能しますが、問題は次のとおりです。

すべてのノードにはエイリアスがあり、そのリスト内で一意である必要があります。

したがって、ルートのすべての子には一意のエイリアスがありますが、すべてのノードは単一のdbテーブルにあります。

ノードが存在するツリーでのみ一意性をチェックするための解決策を知っている人はいますか?

編集:

Baldrickが指摘しているように、カスタム検証を使用するとうまくいきません。問題は、検証ルートでnilが返されることです。以下に示すように:

class Baco::Node < ActiveRecord::Base

  set_table_name "baco_nodes"

  acts_as_nested_set :order => :position

  acts_as_list :scope => :parent_id

  default_scope order("parent_id, position")

  validate :alias_uniqueness

  def alias_uniqueness

    p self.parent.parent       # return the root
    p self.parent              # returns the parent
    p self.root                # returns nil

    if parent.nil?
      root = self
    else
      root = self.parent.root
    end

    if root.descendants.index { |node| node != self && node.alias == self.alias }
      errors.add(:alias, "Alias already used")
    end
  end

end

編集2

子を作成するときに問題が発生しました。つまり、まだ親だけがあり、左右の値がない新しいノードです。新しいノードのルートを取得する代わりに、親のルートを取得します。もちろん、これは同じです。カスタム上記の検証が機能するようになりました。

ありがとう

4

1 に答える 1

0

カスタム検証メソッドを使用して、エイリアスが同じルートのノードの子孫によってまだ使用されていないことを確認します。

class Node < ActiveRecord::Base
  validate :alias_uniqueness

  def alias_uniqueness
    if self.root.descendants.index {|node| node != self && node.alias == self.alias}
      errors.add(:alias, "Alias already used")
    end
  end

  ...
end
于 2012-02-10T14:24:36.180 に答える