zoukankan      html  css  js  c++  java
  • 在Rails中使用polymorphic (多态、虚拟) 关联(转)

    在Rails中使用polymorphic (多态、虚拟) 关联

    来自 http://hi.baidu.com/rainchen/item/034bd0d60a24a32938f6f7dd

    现有个场景,有两个model:person和album,需要添加一个图片来做为其头像/封面。添加一个image model,按照以往需要对这几个model做以下关联设置:

    class Person < ActiveRecord::Base
        has_one :image, :dependent => :destroy
    end

    class Album < ActiveRecord::Base
        has_one :image, :dependent => :destroy
    end

    class Image < ActiveRecord::Base
        belongs_to :person
        belongs_to :album
    end

    相应的image的migration要添加上关联字段:
    t.column :person_id, :integer, :null => false, :default => 0
    t.column :album_id, :integer, :null => false, :default => 0

    不复杂,但是麻烦,如果以后加个book model之类的,也需要有个图做封面的,那又要改image model里的关联和migration了,一点都不DRY。

    这时就该 polymorphic 上场了。

    先上代码:

    class Person < ActiveRecord::Base
        has_one :image, :as => :iconable, :dependent => :destroy
    end

    class Album < ActiveRecord::Base
        has_one :image, :as => :iconable, :dependent => :destroy
    end

    class Image < ActiveRecord::Base
        belongs_to :iconable, :polymorphic => true
    end

    解释:

          polymorphic的实现是添加一个虚拟的第三方model(作为原model的一个形态)来维护彼此的联系。
          首先person和album在关联时添加一个:as选项,设置一个虚拟的iconable model,可以直白理解为“每个person都有一个iconable形态的image”。
          然后设置image属于iconable,且设置:polymorphic => true 表明这个iconable model是虚的,仅仅用来维持关联。
          iconable是虚的,但用来维持彼此联系的“证据”还是必须实实在在的,修改image的migration为:

    # 关联对象的id
    t.column :iconable_id, :integer, :null => false, :default => 0
    # 关联对象的类名,如:Person
    t.column :iconable_type, :string, :null => false, :default => ''


    这样就可以在controller里这样使用:
    # 添加:
    @person = Person.new(params[:person])
    @person.build_image(params[:image])
    @person.save

    # 读取:
    @person.image

    # image 的属主:
    @person.iconable

    相关参考:

    SimplePolymorphicAssociation

    HowToUsePolymorphicAssociations

    UnderstandingPolymorphicAssociations

    has_many_polymorphs:简化多对多映射

    has_many_polymorphs for dummies

  • 相关阅读:
    类例程_java战斗程序
    "类"的讲稿
    象棋中“车”的攻击范围_C#
    面向对象_方法_例题
    入门例子
    MyBatis
    MyBatis
    MyBatis
    Spring
    Hibernate学习
  • 原文地址:https://www.cnblogs.com/wws19125/p/3057810.html
Copyright © 2011-2022 走看看