2009-09-02 10 views
1

Mapモデルがあります。このモデルでは、MUD内の特定領域のASCIIアートマップの詳細が定義されています。 IDの代わりに名前を使用して各地図のページにアクセスできるようにしたいので、西洋のIthmiaの地図があれば、(でも/maps/withmia)からアクセスできるようにしたいと考えています。2つの関連するRailsモデルを同時に作成する必要があります

私は、マップに到達するためのパスで使用できる既存のショートネームをすべて含む2番目のモデルMapAliasを持っています。外部キーは、それぞれのエイリアスに格納され、関連するMapのIDを参照します。

私がしたいことは、新しく作成されたそれぞれMapと一緒に新しいMapAliasを同時に作成することです。残念ながら、新しいMapのIDが保存されるまで取得できないようですが、新しいMapAliasを有効/保存するまでは保存したくありません。これを悪化させるのは、MapAliasが第1のエイリアスであること、つまりリンクを生成するエイリアスが何であるかを知りたいということです。つまり、Mapは、これは私にとって循環的な依存関係のようです...

私はまだ何がすべきか分かりませんが、私はモデルコールバックフック(before_saveのようなもの)だけを調べました限られた成功 - 私はまだ対処するために循環依存を持っています。何か案は? =/

答えて

0

さて、時間の公平なビットの後、私は私だと思います実際の解決策があります。私はこの質問を書いたとき、Map has_many MapAlias'es、各MapAliasはMapに属しています。私は最近、私が望んでいたのは別の関連性であることに気付きました。ウェブサイトがそのマップへのリンクで使用するプライマリ名にマップが属しています。私はこれと3つのフックを追加しました.2つは、エイリアスの設定/作成のためのbefore_validation_on_ *、元のアソシエーションのエイリアスのmap_id外部キーの設定のためのafter_createです。

コントローラには単なるマップです。呼び出し保存しますが、内部的に、エイリアスは最初に保存されます。

belongs_to :shortname, :class_name => "MapAlias" # primary name 

before_validation_on_create :add_map_alias 
def add_map_alias 
    self.create_shortname(:title => self.title) 

    @alias_failed = !(self.shortname.errors.empty?) 

    nil 
end 

before_validation_on_update :set_map_alias 
def set_map_alias 
    self.shortname.title = self.title 
    self.shortname.save(false) 

    @alias_failed = !(self.shortname.errors.empty?) 

    nil 
end 

after_create :set_alias_map_id 
def set_alias_map_id 
    self.shortname.update_attribute :map_id, self.id 

    nil 
end 

それはおそらく最も理想的なソリューションではないのですが、それは私の目的のためだけで正常に動作します。いずれにせよ、誰もが助言してくれてありがとう!

1

データベース・トランザクションでそれをすべてラップ:

Map.transaction do 
    # ... save all your stuff ... 
end 

データベースはそれが得意で何を聞かせて...コールバックでの再実装取引をしようとしないでください。それはすべて救われるか、それともどれも救われることはありません。

0

私が一般的に行うことは、同時に2つのモデルを手動で作成することです。つまり、CauseとEffectという2つのモデルがある場合、Causeを作成できるすべての方法(通常はコントローラから)を作成し、Causeが作成された場合にEffectを作成する行をインクルードします(保存されていなくても、メソッドにオブジェクトがまだ存在するため)IDにアクセスできます。

before_saveメソッドと同じように自動ではないかもしれませんが、何が起こっているのか、いつ、前後のメソッドに根ざすことなく見ることができるのが好きです。

0

これをhtml形式で取得しようとしている場合は、コントローラの新しいMapインスタンスでbuildに電話をかけることができます。


# maps_controller.rb 
def new 
    @map = Map.new 
    @map_alias = @map.map_aliases.build 
end 

あり(仮想属性を作成する)ことにもう少しだが、あなたはいくつかのアイデアのために、このスクリーンキャストを見てとることができます。 http://railscasts.com/episodes/75-complex-forms-part-3

関連する問題