我的问题如下。如何从多态模型
加入belongs_to关联有情况
opinion.rb
class Opinion < ActiveRecord::Base
belongs_to :opinionable, :polymorphic => true
belongs_to :category
end
answer.rb
class Answer < ActiveRecord::Base
has_many :opinions, :as => :opinionable
end
我该怎样做?
Opinion.joins(:opinionabe)。所有
它将抛出
ArgumentError:您无法在未指定多态类的情况下创建多态的belongs_to连接!
我如何具体说明我想加入哪个班级?
第二个问题。如何预加载?
Opinion.preload(:opinionable)。所有
工作正常。它将对belongs_to中的每个类进行查询。
但是。如果我想做像
这样的事情Opinion.preload(:opinionable =&gt;:answer_form).all
存在问题,因为一个模型具有此关联而第二个没有。所以它会抛出异常。
所以我怎么能做像
这样的事情Opinion.preload(:answer =&gt;:answer_form,:another_belongs_to_model).all
谢谢,大卫!
答案 0 :(得分:15)
其实如果你做的话
belongs_to :opinionable_answer, :foreign_key => :opinionable_id, :class_name => "Answer", conditions: { opinions: { opinionable_type: "Answer"}}
然后你可以做
Opinion.joins(:opinionable_answer).where(answers: { awesome: true})
答案 1 :(得分:14)
您的Opinion模型似乎没有指定opinionable_type:string
列。
尝试以这种方式更新迁移:
class CreateOpinions < ActiveRecord::Migration
def self.up
create_table :opinions do |t|
t.integer :opinionable_id
t.string :opinionable_type
# ... other fields
t.timestamps
end
end
def self.down
drop_table :opinions
end
end
这将解决您的第二个问题,Opinion.preload(:opinionable).all
应该可以正常运作。
您不能对多态关联进行连接,因为它们可以位于不同的表中,这些表在加载Opinion
模型后检测到。这就是为什么模型需要列opinionable_type
。
如果您尝试这样做,您将获得下一个异常
ActiveRecord::EagerLoadPolymorphicError
:无法急切加载多态关联:opinionable
UPD:添加魔术连接^ _ ^
class Opinion < ActiveRecord::Base
belongs_to :opinionable, :polymorphic => true
belongs_to :opinionable_answer, :foreign_key => :opinionable_id, :class_name => "Answer"
scope :by_type, lambda { |type| joins("JOIN #{type.table_name} ON #{type.table_name}.id = #{Opinion.table_name}.opinionable_id AND #{Opinion.table_name}.opinionable_type = '#{type.to_s}'") }
end
示例:
Opinion.by_type(Answer).to_sql
=> "SELECT \"opinions\".* FROM \"opinions\" JOIN answers ON answers.id = opinions.opinionable_id AND opinions.opinionable_type = 'Answer'"
答案 2 :(得分:0)
我知道这个问题很旧,但是我只花了一个小时寻找类似问题的解决方案(第3条),所以使它起作用的唯一方法是在此处说明解决方案:https://stackoverflow.com/a/25966630/6878997
您的情况是:
<body>
<div>
<form action="/Home/MultiDArrayToView" method="post" id="form">
<input name="s" required/>
<button type="submit">Submit</button>
</form>
</div>
<script src="~/Scripts/jquery-3.3.1.min.js"></script>
<script>
$(document).ready(function () {
$("#form").submit(function (event) {
event.preventDefault(); //prevent default action
var post_url = $(this).attr("action"); //get form action url
var request_method = $(this).attr("method"); //get form GET/POST method
var form_data = new FormData(this); //Creates new FormData object
$.ajax({
url: post_url,
type: request_method,
data: form_data,
contentType: false,
cache: false,
processData: false,
datatype: "json",
success: function (value) {
//here I am getting array from controller method in 'value' but as a 1D array instead I want multidimensional array
debugger;
}
});
});
});
</script>
</body>
似乎很棘手,但是通过这种方式,您将能够执行多个链式联接,例如:
class Opinion < ActiveRecord::Base
# The true polymorphic association
belongs_to :opinionable, polymorphic: true
# The trick to solve this problem
has_one :self_ref, :class_name => self, :foreign_key => :id
has_one :answer, :through => :self_ref, :source => :opinionable, :source_type => Answer
end
。
只要joins(answer: :other_model)
不是opinion.opinionable
,Answer
就会返回opinion.answer
。
希望对您有所帮助!