`

ActiveRecord中表关联的一个问题,belongs_to和has_many不是一一对应的情况。

阅读更多
一个挺有意思的问题,想了半天没有解决办法。

情景是这样的:系统中有两种category,system_category和user_category,所有属性都一样,只是一个是系统分类,一个是用户自己的分类。比如javaeye就是有这样的机制。用户发文时可以同时选择system_category和user_category。假如数据库的设计是system_category和user_category都在一张表categories中。那么Category和Article类的代码大致如下:
# Category.rb
class Category < ActiveRecord::Base
  has_many :articles
end

# Article.rb
class Article < ActiveRecord::Base
  belongs_to  :system_category, :class_name   => "Category", :foreign_key => "system_category_id"
  belongs_to  :user_category,   :class_name   => "Category", :foreign_key => "user_category_id"
end

各位肯定已经注意到了,两边的has_many和belongs_to不是一一对应的。这个时候执行一些语句,结果如下(假设id为1的user cateogry有两个article,id分别为1,2):
Article.find_by_id(1).user_category.id  # => 1
Article.find_by_id(2).user_category.id  # => 1
Category.find_by_id(1).articles            # 出错,说articles没有category_id。

出现以上错误是正常的,但是有什么方法可以解决这个问题吗?当然,我可以在category中声明两个has_many,但是这样显然不符合应用逻辑。我也尝试过使用:finder_sql,但是不知道怎么得到当前category的id,也就没办法手工做查询了。
分享到:
评论
8 楼 yehs220 2007-07-20  
AllenYoung 写道
yehs220 写道
has_many :articles, :finder_sql=>...

麻烦你来告诉我finder_sql里面怎么写?

...articles.system_category_id=... OR articles.user_category_id=...
7 楼 iamawalrus 2007-07-20  
给categories加一个type的column,就可以使用rails提供的polymorphic功能。
详见belong_to中对:polymorphic的解释。
也可以参考acts_as_taggable的实现。
6 楼 AllenYoung 2007-07-20  
hideto 写道
感觉数据库这样设计很别扭,给category加一个flag用来区分system_cate和user_cate会清晰很多

这样需要一个多对多的关系,我不想用,因为代码里面比较麻烦。
5 楼 AllenYoung 2007-07-20  
cvu 写道
像这种外键不是缺省的modelname_id的,要用has_many :foreign_key的吧。

但是你的例子就算用has_many :foreign_key也不知道foreign_key是哪个。按照Rails的mapping规则,这应该是以个多对多(实际上是二对多,不管,也是多对多)。

三个表categories、articles、articles_categories,其中categories有一个属性category_type = [USER|SYSTEM];articles没有xxxx_category_id字段;articles_categories包括两个字段article_id和category_id。

然后,model Category:
  has_many :articles, :through => :article_categories
model Article:
  has_one :system_category, :through => :article_categories, :condition => "category_type = 'SYSTEM'"
  has_one :user_category, :through => :article_categories, :condition => "category_type = 'USER'"

以上伪代码,没有调试过。

这个好像挺有意思,我去试试看。
4 楼 AllenYoung 2007-07-20  
yehs220 写道
has_many :articles, :finder_sql=>...

麻烦你来告诉我finder_sql里面怎么写?
3 楼 hideto 2007-07-19  
感觉数据库这样设计很别扭,给category加一个flag用来区分system_cate和user_cate会清晰很多
2 楼 cvu 2007-07-19  
像这种外键不是缺省的modelname_id的,要用has_many :foreign_key的吧。

但是你的例子就算用has_many :foreign_key也不知道foreign_key是哪个。按照Rails的mapping规则,这应该是以个多对多(实际上是二对多,不管,也是多对多)。

三个表categories、articles、articles_categories,其中categories有一个属性category_type = [USER|SYSTEM];articles没有xxxx_category_id字段;articles_categories包括两个字段article_id和category_id。

然后,model Category:
  has_many :articles, :through => :article_categories
model Article:
  has_one :system_category, :through => :article_categories, :condition => "category_type = 'SYSTEM'"
  has_one :user_category, :through => :article_categories, :condition => "category_type = 'USER'"

以上伪代码,没有调试过。
1 楼 yehs220 2007-07-19  
has_many :articles, :finder_sql=>...

相关推荐

    ActiveRecord简单实例_activerecord.zip

    ActiveRecord还支持关联,如一对一(has_one),一对多(has_many),多对一(belongs_to)和多对多(has_and_belongs_to_many)关系。例如,如果`users`表和`posts`表有关系,可以这样定义: ```ruby class User ...

    Ruby on Rails中的ActiveRecord编程指南

    避免改动缺省的 ActiveRecord(表的名字、主键,等等),除非你有一个非常好的理由(像是不受你控制的数据库)。  把宏风格的方法放在类别定义的前面(has_many, validates, 等等)。  偏好 has_many :through 胜...

    ActiveRecord简单实例代码.zip

    ActiveRecord支持多种关联关系,如`has_many`、`belongs_to`、`has_one`和`has_and_belongs_to_many`。这些关联定义了不同模型之间的关系,例如,一个`User`模型可能`has_many``Posts`,表示用户可以有多个帖子。 ...

    fixture_dependencies:SequelActiveRecord夹具加载器,用于处理依赖关系图

    支持many_to_one / belongs_to,one_to_many / has_many,many_to_many / has_and_belongs_to_many和has_one / one_to_one关联 以不违反外键约束的方式加载灯具的依赖关系图 有一个非常简单的API...

    has_array_of:PostgreSQL数组上的ActiveRecord关联

    该插件使用PostgreSQL数组的功能实现了在Rails中进行has_and_belongs_to_many关联的替代方法。 在很多情况下,你只需要或的功能使用许多一对多与连接表是不必要的传统方法。 我们可以只存储id的整数数组。 它是如何...

    Python-OratorORM提供了一个简单而优美的ActiveRecord实现

    4. **关联关系**:Orator ORM也支持多种数据库关联,如一对一(`hasOne`),一对多(`hasMany`),多对一(`belongsTo`),多对多(`belongsToMany`)。这使得处理复杂的数据关系变得更加直观。 例如,定义用户和...

    ruby声明式语法的实现例子

    has_many和belongs_to其实是Topic类的class method,标准写法是: 代码如下: class Topic &lt; ActiveRecord::Base  Topic.has_many(:posts)  Topic.belongs_to(:user) end 那么has_many可以给我们带来什么呢?...

    association_callbacks:ActiveRecord关联的回调

    提供一种将一个模型的定义为关联模型的方法。 例子 首先,两个简单的Article和Comment模型: class Article &lt; ActiveRecord :: Base has_many :comments end class Comment &lt; ActiveRecord :: Base belongs...

    Yii2 ActiveRecord多表关联及多表关联搜索的实现

    在关联过程中,我们通常使用`hasOne`、`hasMany`、`belongsTo`等方法定义模型间的一对一、一对多或多对一的关系。以用户表`user`和用户渠道表`auth`为例,假定`user`表通过`id`与`auth`表通过`uid`字段进行一对一...

    简单Castle.ActiveRecord.Generator

    例如,`[ActiveRecord]`用于标记一个类为ActiveRecord实体,`[PrimaryKey]`用于标识主键字段,`[BelongsTo]`或`[HasMany]`用于定义关联关系。 3. **数据库操作方法**:这些方法包括`Save()`(用于创建或更新记录)...

    ruby on rails在线考试系统

    5. Active Record关联:Rails中的ActiveRecord模型可以定义多种关联,如 belongs_to、has_many、has_one 和 has_and_belongs_to_many。在线考试系统中,试题可能 belongs_to 一个类别,考生 has_many 考试记录。 6....

    amoeba:Ruby宝石,允许复制ActiveRecord对象及其关联的子对象,可通过模型上的DSL配置

    has_and_belongs_to_many 一个简单的DSL,用于配置要复制的字段。 DSL可以应用于您的Rails模型或即时使用。 支持STI(单表继承)子代继承其父变形虫设置。 多种配置样式,例如包含,排除和不

    ruby多模型绑定

    在 Rails 中,有几种基本的关联类型:`belongs_to`, `has_many`, `has_one`, `has_and_belongs_to_many`等。这些关联类型可以用来表示不同模型之间的关系,例如一对多关系、多对一关系、多对多关系等。 #### 2.1 ...

    Ruby-Unread管理ActiveRecord对象的已读未读状态

    belongs_to :sender has_many :read_marks, as: :readable, class_name: 'Unread::ReadMark' end ``` 接下来,我们为读取者(例如User)模型添加相应的关联: ```ruby class User include Unread::Reader ...

    Ruby-pgsearch利用PostgreSQL的全文搜索构建ActiveRecord的命名空间

    在这个例子中,`Article`模型被扩展了`pg_search_scope`方法,定义了一个名为`search_by_title_and_content`的搜索范围,它会针对`title`和`content`字段进行全文搜索,且使用英文词汇表。 使用这个定义,我们可以...

    effective_datatables:对于Ruby on Rails,有效的ActiveRecord到Datatables dsl。 快速制作智能表

    强大的服务器端搜索,排序和筛选ActiveRecord类(具有belongs_to和has_many关系)。 通过搜索sql列以及ActiveRecord和Array集合中的计算值来做正确的事情。 显示基于current_user授权操作的关联编辑/显示/销毁...

    显示关联轨道NYC04-SENG-FT-053120

    创建has_many和belongs_to关联。 通过控制台和db/seeds.rb构建关联的数据。 使用关联提供的方法查询关联数据。 将关联数据嵌入视图中。 遍历显示单个实例的视图内的关联数据。博客类别在本课程中,我们将设置一个...

    query_methods_extend

    查询方法扩展 在 rails 4 扩展查询 activerecord 安装 将此行添加到应用程序的 Gemfile 中: ... belongs_to :store has_many :books end // Category ( id : integer , name : string , store_id : integer ) cla

    Castle ActiveRecord 手册

    4. **关系映射**:对于多对一、一对多、多对多的关系,Castle ActiveRecord提供了`BelongsTo`、`HasMany`和`HasAndBelongsToMany`特性。这些特性用于定义实体间的关联,简化了数据库交互。 5. **事务管理**:Castle...

Global site tag (gtag.js) - Google Analytics