[解決済み] 複数の外部キーを持つRailsのアソシエーション
質問
1つのテーブルで2つのカラムを使用して関係を定義できるようにしたいです。例としてタスクアプリを使用します。
試み1。
class User < ActiveRecord::Base
has_many :tasks
end
class Task < ActiveRecord::Base
belongs_to :owner, class_name: "User", foreign_key: "owner_id"
belongs_to :assignee, class_name: "User", foreign_key: "assignee_id"
end
では
Task.create(owner_id:1, assignee_id: 2)
これによって
Task.first.owner
を返します。
ユーザー1
そして
Task.first.assignee
を返すと
ユーザ2
しかし
User.first.task
は何も返しません。これはタスクがユーザーに属していないためです。
オーナー
に属しており
譲受人
. だから
試み2。
class User < ActiveRecord::Base
has_many :tasks, foreign_key: [:owner_id, :assignee_id]
end
class Task < ActiveRecord::Base
belongs_to :user
end
2つの外部キーがサポートされていないようなので、これは完全に失敗しています。
ですから、私が欲しいのは、次のように言えるようにすることです。
User.tasks
と入力して、所有するユーザーと割り当てられたタスクの両方を取得することです。
基本的にどうにかして、以下のクエリに等しいリレーションを構築します。
Task.where(owner_id || assignee_id == 1)
それは可能ですか?
更新情報
を使用することは考えていません。
finder_sql
を使いたいわけではないのですが、この問題の未受理回答は私が欲しいものに近そうです。
Rails - 複数のインデックスキーの関連付け
ということで、このメソッドは以下のような感じになります。
試み3。
class Task < ActiveRecord::Base
def self.by_person(person)
where("assignee_id => :person_id OR owner_id => :person_id", :person_id => person.id
end
end
class Person < ActiveRecord::Base
def tasks
Task.by_person(self)
end
end
で動作させることはできるのですが
Rails 4
では動作するのですが、以下のようなエラーが発生します。
ActiveRecord::PreparedStatementInvalid: missing value for :owner_id in :donor_id => :person_id OR assignee_id => :person_id
どのように解決するのですか?
TL;DR
class User < ActiveRecord::Base
def tasks
Task.where("owner_id = ? OR assigneed_id = ?", self.id, self.id)
end
end
削除
has_many :tasks
で
User
クラスで使用されます。
使用方法
has_many :tasks
という名前のカラムがないため、全く意味をなしません。
user_id
という名前のカラムがないからです。
tasks
.
私の場合、問題を解決するために行ったことは
class User < ActiveRecord::Base
has_many :owned_tasks, class_name: "Task", foreign_key: "owner_id"
has_many :assigned_tasks, class_name: "Task", foreign_key: "assignee_id"
end
class Task < ActiveRecord::Base
belongs_to :owner, class_name: "User", foreign_key: "owner_id"
belongs_to :assignee, class_name: "User", foreign_key: "assignee_id"
# Mentioning `foreign_keys` is not necessary in this class, since
# we've already mentioned `belongs_to :owner`, and Rails will anticipate
# foreign_keys automatically. Thanks to @jeffdill2 for mentioning this thing
# in the comment.
end
この方法では
User.first.assigned_tasks
と同様に
User.first.owned_tasks
.
というメソッドを定義することができます。
tasks
の組み合わせを返す
assigned_tasks
と
owned_tasks
.
読みやすさに関しては良い解決策かもしれませんが、パフォーマンスの観点からは、今までのように
tasks
を取得するために、1回ではなく2回のクエリを発行し、その2つのクエリの結果も結合する必要があるからです。
したがって、あるユーザーに属するタスクを取得するために、カスタムな
tasks
メソッドを
User
クラスを以下のように変更します。
def tasks
Task.where("owner_id = ? OR assigneed_id = ?", self.id, self.id)
end
この方法では、1つのクエリですべての結果を取得するため、結果をマージしたり結合したりする必要はありません。
関連
-
[解決済み】bundle installが "Could not locate Gemfile "を返す。
-
[解決済み】コントローラでJSONをレンダリングする
-
[解決済み] rake db:migrateを使って1ステップだけロールバックする方法
-
[解決済み] どなたか、collection_selectをわかりやすく説明していただけませんか?
-
[解決済み] Errno::EACCESS: パーミッションが拒否された @ dir_s_mkdir
-
[解決済み] Paramが無いか、値が空である。ParameterMissing in ResultsController#update
-
[解決済み] railsでhidden fieldタグを使用する方法
-
[解決済み] Rails / Haml: 投稿フォームを作成するには?
-
[解決済み] railsでcheck_boxをcheckedにする方法は?
-
[解決済み] Ruby on Railsのマイグレーションでデータベースのカラムの名前を変更するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】警告:定数 ::Fixnum は非推奨 新しいモデルを生成するとき
-
[解決済み】コレクションをDESCで並べる方法
-
[解決済み] ウェブパッカーがアプリケーションを見つけ出せない
-
[解決済み] PG::ConnectionBad - サーバーに接続できませんでした。接続が拒否されました。
-
[解決済み] rails erb フォームヘルパー options_for_select :selected
-
[解決済み] railsアプリケーションでCookieのオーバーフロー?
-
[解決済み] Rails / Haml: 投稿フォームを作成するには?
-
[解決済み] Rspec が私のモデルクラスを認識しない。初期化されていない定数エラー
-
[解決済み] Heroku: 既存のrailsアプリにseeds.rbをプッシュする方法?
-
[解決済み] Railsコンソール:リロード!モデルファイルの変更が反映されない?考えられる理由は何でしょうか?