`
deferling
  • 浏览: 17011 次
  • 性别: Icon_minigender_1
  • 来自: 东京
文章分类
社区版块
存档分类
最新评论

rails 框架里的模型(模型)继承和类的问题

阅读更多
开发中遇到一个问题
ReportRequest是一个表对应一个model:report_request.rb

model report_request.rb 里面
class ReportRequest < ActiveRecord::Base

model TeikiRecountRequest.rb 里面
class TeikiRecountRequest < ActiveRecord::Base

model spot_report_request.rb 里面
class SpotReportRequest < ReportRequest

现在用 ReportRequest.find 方法在数据库里取数据
为什么取出来的对象会是SpotReportRequest 或者 TeikiRecountRequest 的类的对象

请教大家谢谢
分享到:
评论
14 楼 amonlei 2008-08-24  
楼主有点懒惰哟,自己写几行代码试试就出来了。。。。另外说一句:继承超过2层的话,rails的控制器会认不出来,应该是bug,但是单元测试认得出来,大家可以试试。。
13 楼 deferling 2008-08-22  
怎么出来左手,申明一下不是左撇子
赫赫
12 楼 deferling 2008-08-22  
非常感谢!!!
11 楼 liusong1111 2008-08-22  
不用客气。
单表继承(STI)是指一个table对应多个class,这些class继承自同一父class。
对,单表继承是相对于多表继承。多table对应多class的情况,其中还可分 父class要不要单独对应一张表。
对于rails,我们也只用到了STI这一种。
跟表映射无关的代码重用,可以用继承,也可以用ruby的mixin。
10 楼 deferling 2008-08-22  
liusong1111 写道
A.find_xx就返回A的对象呗,有type字段的,是作为单表继承的。

恩,
不好意思,耽误你时间了
还有个问题单表继承是相对于多表继承?
意思是B和C只是单一继承Amodel?
真不好意思,麻烦了
9 楼 liusong1111 2008-08-22  
A.find_xx就返回A的对象呗,有type字段的,是作为单表继承的。
8 楼 deferling 2008-08-22  
表是自己建的,万一没有type字段怎么办?
7 楼 liusong1111 2008-08-22  
deferling 写道
恩,是有type的,好厉害!
那我想问一下也就是说有一个model A,对应的是table表(映射关系?),
A分别派生了C跟B,table里面的type只要是C那就被认为是C的对象
table里面的type只要是B那就被认为是B的对象,是这么一回事情吗,
如此智能。。。。?


小弟刚刚做ruby on rails 以前是做c++的,源代码暂时还看不懂全部的意思,希望和大家一起进步。




nod nod 
6 楼 deferling 2008-08-22  
恩,是有type的,好厉害!
那我想问一下也就是说有一个model A,对应的是table表(映射关系?),
A分别派生了C跟B,table里面的type只要是C那就被认为是C的对象
table里面的type只要是B那就被认为是B的对象,是这么一回事情吗,
如此智能。。。。?


小弟刚刚做ruby on rails 以前是做c++的,源代码暂时还看不懂全部的意思,希望和大家一起进步。


5 楼 liusong1111 2008-08-22  
我看的是rails-1.2.3的源码。
今天比较忙,有时间再跟大家一起学习。

源码大体是,调哪个类的find方法,就生成哪个类的实例。
单表继承的 会生成具体子类的实例。
确认子类名的依据,参考上面代码的17行和29行:如果表中有字段名为type,则该记录的字段值就代表了子类名。
如果不想用type这个名字,可以通过set_inheritance_column定制。但rails把 数据库值和子类名直接对应,没有提供接口让我们定制它们的映射关系(compute_type只是简单的确保不让类名前面的module忽略掉)。

--
切到笔记本,终于可以不用蹩脚的英文了。
4 楼 deferling 2008-08-22  
<p>assocations.rb can not be find.<br/>in callbacks.rb</p>
<p> </p>
<pre name='code' class='ruby'>    # Is called when the object was instantiated by one of the finders, like Base.find.
    #def after_find() end

    # Is called after the object has been instantiated by a call to Base.new.
    #def after_initialize() end</pre>
<p> so i still don't know why </p>
<p> can u explain it more detailed?</p>
<p> thks a lot<img src='../../../../../images/smiles/icon_smile.gif' alt=''/></p>
3 楼 liusong1111 2008-08-22  
rails code in activerecord/lib/activerecord/base.rb:
module ActiveRecord 
  class Base
    class << self
      # Works like find(:all), but requires a complete SQL string. Examples:
      #   Post.find_by_sql "SELECT p.*, c.author FROM posts p, comments c WHERE p.id = c.post_id"
      #   Post.find_by_sql ["SELECT * FROM posts WHERE author = ? AND created > ?", author_id, start_date]
      def find_by_sql(sql)
        connection.select_all(sanitize_sql(sql), "#{name} Load").collect! { |record| instantiate(record) }
      end


# Finder methods must instantiate through this method to work with the
        # single-table inheritance model that makes it possible to create
        # objects of different types from the same table.
        def instantiate(record)
          object =
            if subclass_name = record[inheritance_column]
              if subclass_name.empty?
                # No type given.
                allocate
              else
                # Ignore type if no column is present since it was probably
                # pulled in from a sloppy join.
                unless columns_hash.include?(inheritance_column)
                  allocate

                else
                  begin
                    compute_type(subclass_name).allocate
                  rescue NameError
                    raise SubclassNotFound,
                      "The single-table inheritance mechanism failed to locate the subclass: '#{record[inheritance_column]}'. " +
                      "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " +
                      "Please rename this column if you didn't intend it to be used for storing the inheritance class " +
                      "or overwrite #{self.to_s}.inheritance_column to use another column for that information."
                  end
                end
              end
            else
              allocate
            end

          object.instance_variable_set("@attributes", record)
          object
        end

    end
  end
end


YourClass.find_xxx will get one or more record(Hash), call YourClass.allocate to create instance for each, and populate properties to them.
while single table inheritance return corresponding subclass instance.

Q: what's allocate?
A: allocate memory for the newly created instance, without calling constructor(initialize).
  
YourClass.new(*args) 

    equal to
   YourClass.allocate.initialize(*args)


search "instantiate" in activerecord source code, you will find callbacks.rb rewrites it to enable "after_find" and "after_initialize" callbacks, and assocations.rb how to manage join table instantiate.



2 楼 deferling 2008-08-22  
class TeikiRecountRequest < ActiveRecord::Base
  establish_connection "#{ENV['RAILS_ENV']}"
  belongs_to :teiki_report_request
  has_and_belongs_to_many :product_references
 
  alias report_request :teiki_report_request
  alias products :product_references
end


class SpotReportRequest < ReportRequest
  has_and_belongs_to_many :sources,
      :join_table  => 'report_requests_sources',
      :foreign_key => 'report_request_id'
  has_and_belongs_to_many :subjects,
      :join_table  => 'report_requests_subjects',
      :foreign_key => 'report_request_id'

  has_many :topic_keywords, :class_name => "TopicKeyword", :finder_sql =>
      'SELECT DISTINCT tkw.* ' +
      'FROM topic_keywords tkw, report_requests rr ' +
      'WHERE rr.id = #{id} AND rr.topic_keyword_type = tkw.type ' +
      'ORDER BY tkw.name'
  has_many :evaluations
  has_many :job_report_item_generator, :dependent => :destroy
  has_one :report_file

这点够不够
这个继承的model在数据库里 是如何生成数据表的呢?
继承的model在数据库里生成数据表的方法有哪些能请教一下吗
1 楼 yangtao309 2008-08-22  
deferling 写道

model report_request.rb 里面
class ReportRequest < ActiveRecord::Base

model spot_report_request.rb 里面
class SpotReportRequest < ReportRequest


这个继承的model在数据库里 是如何生成数据表的呢?

相关推荐

    Ruby-MongoModel针对MongoDB的RubyORM框架兼容Rails3

    在Ruby on Rails框架中,ORM(对象关系映射)框架如ActiveRecord允许开发者以面向对象的方式处理数据库操作,而无需直接编写SQL语句。MongoModel作为针对MongoDB的ORM,同样提供了这种便利性,但适应了文档数据库的...

    ruby on rails 2.3.5 api html版

    这包括变量、常量、方法、类、模块、继承和元编程等概念。 2. **Rails MVC结构**:模型(Model)处理数据和业务逻辑,视图(View)负责展示,控制器(Controller)协调两者。在Rails中,这些组件通过ActiveRecord、...

    Rails API 文档

    Rails API文档是Ruby on Rails框架的核心参考资料,专为开发者提供详细的API接口信息和技术指南。Rails是基于Ruby语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,极大地简化了Web开发过程...

    Ruby on Rails入门经典代码

    - Mixins:Ruby的模块系统允许类间共享代码,实现类似多重继承的功能。 3. **Rails生成器**: - `rails new`:创建新Rails项目。 - `generate controller`:创建控制器,生成相关的动作和视图文件。 - `...

    Ruby on Rails入门例子

    在Rails中,我们通常使用ActiveRecord库来创建模型,通过继承`ApplicationRecord`类并定义属性和关系。 2. **View**:视图负责展示用户界面。Rails提供了ERB(Embedded Ruby)模板,允许在HTML中嵌入Ruby代码,实现...

    Ruby_On_Rails笔记

    Rails框架的核心是遵循MVC(模型-视图-控制器)设计模式,它将应用程序分为三个主要部分,模型(Model)、视图(View)和控制器(Controller),每部分都有其特定的职责。 Rails起步章节中提到了安装Rails的过程。...

    ruby 例子 模仿rails 的 mvc

    这些类继承自`ActiveRecord::Base`,这是Rails框架提供的一个基类,它提供了与数据库交互的能力,如查询、创建、更新和删除记录。例如: ```ruby class User # 定义关联、验证和其他业务逻辑 end ``` **视图...

    ruby on rails 2.2.2 参考手册

    它提供了详尽的API文档,帮助开发者深入理解Rails框架中的各个组件和方法。以下是一些关键的知识点: 1. **MVC架构**:Rails的核心设计模式是Model-View-Controller(MVC),分别处理数据、用户界面和应用程序逻辑...

    Beginning Rails 4

    - **面向对象编程**:类、对象、继承、多态等概念。 - **高级特性**:块、迭代器、元编程等。 #### 第5章:与数据库交互:ActiveRecord 这一章节介绍了 Rails 中的核心 ORM(对象关系映射)组件 ActiveRecord。...

    Agile Web Development with Rails for Rails 3.2

    Rails 3.2是Ruby on Rails框架的一个重要版本,它对前一版本进行了大量的改进和优化,包括提高了性能、增强了安全性,并引入了一些新的功能。这一版本继续支持Ruby 1.8.7及以上版本,并针对Ruby 1.9.x进行了优化。 ...

    rails tutorial

    1. **Ruby基础知识**:首先,你需要对Ruby编程语言有一定的了解,包括变量、常量、数据类型、控制结构、函数和面向对象编程的概念,如类、继承、模块和方法等。 2. **Rails安装与配置**:教程会指导如何在不同的...

    mid.zip_Rails

    开发者可以定义模型类,这些类将继承自ActiveRecord::Base,提供诸如验证、关联和其他数据库操作的方法。 2. **Views**:视图负责展示数据,通常由HTML、ERB(Embedded Ruby)或其他模板语言组成。它们与控制器交互...

    Ruby on Rails 指南 v5.0.1 中文版

    **:Rails是一种用于开发服务器端应用程序的模型-视图-控制器(MVC)框架,它使用Ruby编程语言,通过约定优于配置的原则,简化了Web应用程序的开发过程。 - **创建Rails项目**:介绍如何使用`rails new`命令来生成一...

    Rails相关电子书汇总二

    2. **Rails框架核心概念**:如路由(Routes)、控制器(Controllers)、模型(Models)、视图(Views)、ActiveRecord、ActionMailer、ActionCable等。 3. **数据库交互**:通过ActiveRecord理解ORM(对象关系映射)...

    ruby on rails入门基础

    - 使用`gem install rails`命令安装最新版本的Rails框架。 3. **Rails项目创建**: - 使用`rails new`命令创建新的Rails应用,如`rails new myapp`,这会生成一个包含所有必要文件和目录的项目结构。 4. **MVC...

    资源for rails

    然后通过`gem install rails`命令来全局安装Rails框架。Rails的版本管理工具如RVM(Ruby Version Manager)或rbenv可以帮助管理多个Ruby版本。 2. **数据库集成**:Rails默认使用SQLite数据库,但也可以配置为使用...

    rails 2.3.5开发就业指导中心网站部分记录

    "源码"标签提示我们将关注代码结构、设计模式和Rails框架的核心组件。"工具"标签则可能意味着会涉及开发过程中的辅助软件,如数据库管理工具、版本控制系统(如Git)或者调试器。 在Rails 2.3.5中,开发者可能使用...

    ruby on rails源代码分析

    这个过程涉及到了 Rails 框架的核心组件,如数据库适配器、路由、控制器、模型和视图等。理解这些启动步骤对于深入理解 Rails 的工作原理至关重要,也有助于开发者在遇到问题时能够快速定位和解决问题。 总之,...

    <<Ruby for Rails中文版>>源代码

    《Ruby for Rails中文版》是一本深入探讨Ruby on Rails框架的书籍,它的源代码提供了丰富的实践示例,帮助读者更好地理解和应用Rails开发技巧。在这个压缩包中,包含了多个与Rails编程相关的文件,如`r4rmusic-1`、`...

Global site tag (gtag.js) - Google Analytics