Rails 2.3.4:如何根据自己的类型过滤共享相同表的模型?
考虑以下示例代码:(
def Product < ActiveRecord::Base
end
def Book < Product
end
我放弃了为这种关系寻找名称。我认为 Book 是“子模型”,Product 是“父模型”,但这是不正确的。例如,链接到的 Comment 模型对象另一个 Comment 模型对象是“子-父”关系,如果您有更好的方法来描述我上面的代码中的模型关系,欢迎您在这里写下来,无论如何,这都不是。真的是我来这里的原因。)
当然,通过上面的代码,书籍模型将与产品“产品”共享相同的数据库表。模型类型将作为字符串保存在表的“类型”列中。因此,调用 Product.create 将在表中插入一行,并将类型值设置为“Product”,并且使用 Book.create 将执行相同的操作,但值为“Book”。
然而,令我困惑的是,正如我所期望的那样,调用 Book.last 将返回类型为“Book”的最后一行,但 Product.last 无论是什么类型(包括“Product”和“Book”)都会返回最后一行, ”尽管我只想得到最后一个“产品”。
我尝试在 Product 中定义一个 default_scope ,并在 Book 中覆盖它,但这会导致比它解决的问题更多的问题,并且弄乱了 Product 中由 Book 继承的命名范围。
有没有办法让 Product.last 返回“Product”类型的最后一个对象并避免任何“Book”类型的对象?
预先感谢您的回答。
Consider the following example code:
def Product < ActiveRecord::Base
end
def Book < Product
end
(I gave up finding a name for this kind of relationship. I thought Book is a "child model" and Product is the "parent," but that is incorrect. For example, a Comment model object linked to another Comment model object is what would be a "child-parent" relationship. If you have a better way to describe the relationship of the models in my code above, you're welcome to write it down here. Either way, this is not really why I'm here.)
Of course, with the code above, the Book model will share the same database table than Product, "products." The model type will be saved as a string in the table's "type" column. So, calling Product.create will insert a row in the table with the type value set to "Product" and using with Book.create will do the same but with the value of "Book."
What puzzles me, however, is calling Book.last will return the last row with the type "Book," as I expect it, but Product.last will return the last row no matter what type, including "Product" and "Book," even though I wish to only get the last "Product."
I tried defined a default_scope in Product which I override in my Book, but that causes more problems than it solves, and messed up my named scopes in Product which are inherited by Book.
Is there a way to make Product.last return the last object of type "Product" and avoid any objects of type "Book"?
Thanks in advance for your answers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里的基本误解似乎是在“关系”或“关联”的概念(例如“has_one”、“belongs_to”等)与面向对象的继承概念之间。
阅读此内容: http://rubylearning.com/satishtalim/ruby_inheritance.html
根据您的示例,我认为您已经弄清楚了关联的概念,但您将其与继承混淆了,这不是同样的,你在这里不太明白。
当一个类从另一个类继承时(在您的示例中,Book 继承自 Product),“子”类将获取“父”类的所有功能,以及它在其之上添加的任何新功能。
因此,所有书籍都是产品,但并非所有产品都是书籍。
无论类型如何,Product.last 都会返回产品表中的最后一行,因为所有产品(包括书籍)都是产品。因此,一本书是一种产品,因此如果最后一个产品是一本书,则该产品将被退回。
好的,完成您在此处尝试执行的操作的最简单方法是将所有类型的产品定义为产品的子类型,并且永远不要使用 Product.last。
假设您正在跟踪书籍、CD 和汽车
类 Book <<产品
CD级<产品
车类<这样
,当您需要将最新的 Book、CD 或 Car 添加到数据库中时,您可以执行 Book.last、CD.last 或 Car.last。如果您只需要了解任何类型的最新产品,则可以执行 Product.last。
The basic misunderstanding here seems to be between the concept of "relationships" or "associations" (such as "has_one", "belongs_to", etc.), and the object oriented concept of inheritance.
Read up on this: http://rubylearning.com/satishtalim/ruby_inheritance.html
Based on your example, I think you've got the concept of associations figured out, but you're confusing it with inheritance, which isn't the same, and you're not quite understanding here.
When a class inherits from another class (in your example, Book inherits from Product), the "child" class gets all the functionality of the "parent" class, plus any new functionality that it adds on top of that.
Because of that, all Books are Products, but not all Products are Books.
The reason Product.last returns the last row in the products table regardless of type, is because all Products (including Books) are products. So, a Book IS a product, therefore if the last Product is a Book, that will be returned.
Ok, so the easiest way to accomplish what you're trying to do here is to define all types of Products as sub-types of Product, and never use Product.last.
Let's say you're keeping track of Books, CDs, and Cars
class Book < Product
class CD < Product
class Car < Product
This way, when you need to get the newest Book, CD, or Car added to the database, you do Book.last, CD.last, or Car.last. If you just need to know the newest Product of any type, you do Product.last.
在我看来,Product.last 应该返回最后一行,因为所有内容都是表中的“产品”,这一点非常清楚。您想要做的是搜索特定类型“Product”,但事实证明该表实际上并未为 Product 设置类型,只是将其保留为零。
所以这确实有效,我想:
你能尝试一下吗?我在不同的桌子上进行了测试,但我认为这应该可行。
It seems to me pretty clear that Product.last should return the last row, since everything is a "Product" in your table. What you want to do is search for the specific type "Product", but as it turns out the table doesn't actually set a type for Product, it just leaves it nil.
So this actually works, I think:
Can you try it out? I tested on a different table but I think this should work.