私の答えは、あなたがただ一つuser
になりたいだけだと仮定しています。を複数で使用したい場合は、@ ariの答えは良いと思いますが、の代わりに選択することもできます。roomie
dwelling
user
roomie
dwelling
has_and_belongs_to_many
has_many :through
今私の答えのために:
belongs_to
私はそれを所有者とhas_many
部屋(おそらく所有者を含むが必ずしもそうではない)の住居になるように設定しました。
とのUser
両方のモデルを使用できます。追加のテーブルやモデルは必要ありません。オプションを使用して適切な関係を設定するだけです。owners
roomies
:class_name
:foreign_key
モデルDwelling
内:
# dwelling.rb
belongs_to :owner, :class_name => "User", :foreign_key => "owner_id"
has_many :roomies, :class_name => "User"
モデルUser
内:
# user.rb
belongs_to :dwelling # This is where the user lives
has_many :properties, :class_name => "Dwelling", :foreign_key => "owner_id" # This is the dwellings the user owns
テーブルには、所有者のを格納するための列dwellings
が必要ですowner_id
user_id
テーブルには、ユーザーが住んでいる住居を保存users
する必要があります。dwelling_id
dwelling_id
コントローラに関するコメントであなたの質問に答えるには:
current_user
新しい住居の所有者として設定する場合は、次のようにします。
@dwelling = current_user.properties.build(params[:dwelling])
....
current_user
新しい住居の所有者および部屋の所有者として設定する場合は、次のようにします。
@dwelling = current_user.properties.build(params[:dwelling]
if @dwelling.save
current_user.dwelling = @dwelling
if current_user.save
# flash and redirect go here
else
# It's not clear why this wouldn't save, but you'll to determine
# What to do in such a case.
end
else
...
end
上記の最も難しい部分は、住居が有効で保存されている場合を処理することですが、何らかの無関係な理由current_user
で保存できません。アプリケーションによっては、ルーミーとして割り当てることができない場合でも、とにかく住居を保存したい場合がありますcurrent_user
。または、住居を保存しないようにすることもできます。保存する場合は、モデルトランザクションを使用する必要がありますが、これはこの質問の範囲を少し超えています。
current_user
Dwellingを保存しても実際にはレコードが更新されて保存されないため、コントローラーコードは機能しませんでしたdwelling_id
。コードは次のようになります。
@dwelling = Dwelling.new(params[:dwelling])
current_user.dwelling = @dwelling
if @dwelling.save
...
current_user
それは決して保存されないので、そのcurrent_user.dwelling = @dwelling
行は役に立たないことに注意してください。
これは直感に反しているように見えるかもしれませんが、肝心なのは、build_dwelling
期待どおりに実際にメモリに設定されていないということです。構築しているモデルではなく、構築しているモデルを保存すると、より直感的な結果が得られます。
@dwelling = current_user.build_dwelling(params[:dwelling])
if current_user.save # This will save the dwelling (if it is valid)
ただし、これは(デフォルトで)検証エラーがある場合:autosave
、関連付けをオンにしない限り住居を保存しません。これもこの質問の範囲を少し超えています。私は本当にこのアプローチをお勧めしません。
アップデート:
より詳細なコードスニペットは次のとおりです。**
# dwellings_controller.rb
def create
@dwelling = current_user.properties.build(params[:dwelling])
if @dwelling.save
# The current user is now the owner, but we also want to try to assign
# his as a roomie:
current_user.dwelling = @dwelling
if current_user.save
flash[:notice] = "You have successfully created a dwelling"
else
# For some reason, current_user couldn't be assigned as a roomie at the
# dwelling. This could be for several reasons such as validations on the
# user model that prevent the current_user from being saved.
flash[:notice] = "You have successfully created a dwelling, but we could not assign you to it as a roomie"
end
redirect_to current_user
else
# Dwelling could not be saved, so re-display the creation form:
render :new
end
end
住居が正常に保存されると、現在のユーザーが(owner_id
データベース内の)所有者になります。ただし、current_user
が保存されない場合は、アプリケーションがそれにどのように応答するかを決定する必要があります。上記の例では、住居を保存することを許可していますが(つまり、作成をロールバックしません)、ユーザーに部屋を割り当てることができなかったことを通知します。これが発生した場合、問題の原因はアプリケーション内の他のコードである可能性があります。のエラーを調べて、そのcurrent_user
理由を確認できます。current_user.save!
または、一時的にではなく、を使用current_user.save
してトラブルシューティングを行うこともできます。
これをすべて行う別の方法は、モデルafter_create
でコールバックを使用することです。Dwelling
多くの点で、それはよりクリーンで簡単な方法です。ただし、current_user
保存できない場合のケースのキャッチは、処理方法によっては、上記の方法よりもさらに醜い場合があります。
肝心なのは、current_user.save
コードがいくつかの問題を引き起こしているということだと思います。その理由を診断し、その場合にアプリケーションが何をすべきかを判断する必要があります。これを処理するには、少なくとも次のようないくつかの方法があります。
- すべてをトランザクションブロックに入れ、
current_use.save!
代わりにを使用current_user.save
して、例外が発生し、ユーザーも住居も保存されないようにします。
- 住居を保存しますが、彼は部屋の人ではないことをユーザーに知らせます(上記のように)
- current_userを保存する代わりに、を使用します
update_column
(これにより、コールバックや検証などが回避されます)。
あなたが経験している現在の問題は、本質的に元の質問とは無関係であると私は信じています。さらに支援が必要な場合は、別の質問としてそれを中断するのが最善かもしれません。