该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-03-01
ruby和rails的文章看了不少.不过都没有看到过讲述如何在rails下面,按模块来分类model的资料(比如像java那样用包来分类java文件,呵呵 ...我是一个java程序员). 我也试了一下把不同功能的model放在model(rails默认的)文件夹下面的子文件夹(模块,也是包),也是可以成功的,不过这样做的话,rails的约定高于配置就用不上了,因为要自己指定各个类的class.比如: has_one :my_test,:class_name => 'Content::MyTest' 这样. 我觉得这样比较不爽.
另外, include Human 这样的代码在model和controller里面似乎并不起它就有的作用.比如:我有一Human::User的类,在controll入er里面加 include Human,再使用 User.new 这样的代码就会出错,提示也就是说找不到User类云云....
最后的感觉就是,rails的约定优于配置思想,确实是还来了好多方便,不过有时候未免不能随心所欲. 呵呵 ...... 也许是我强求了.
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-03-01
ruby module又不是java的package,import一下就可以不写package name了
多写个class_name又怎么了? |
|
返回顶楼 | |
发表时间:2008-03-01
建模要适度,OO别滥用
|
|
返回顶楼 | |
发表时间:2008-03-01
按模块来分类model其实是有的,只是楼主还没有完全理解rails的autoloading-class机制
比如在"app/model"下,建立一个文件夹"demo",在下面创建两个模型 # model class class Demo::Public < ActiveRecord::Base has_many :books end class Demo::Book < ActiveRecord::Base belongs_to :public end # migration script: def self.up create_table :publics do |t| t.string :name end create_table :books do |t| t.integer :public_id t.string :title end end def self.down drop_table :publics drop_table :books end 可以用console测试,两个model工作完全正常,因为两个模型在一个scope内,所以不需要class_name来指定类名,classload会优先在本地scope中查找class: > public1 = Demo::Public.new(:name => "O'Reilly") => #<Demo::Public id: nil, name: "O'Reilly"> > public1.books << Demo::Book.new(:title => "Ruby CookBook") => [#<Demo::Book id: nil, public_id: nil, title: "Ruby CookBook">] > public1.save Demo::Public Create (0.000635) INSERT INTO publics ("name") VALUES('O''Reilly') Demo::Book Create (0.000202) INSERT INTO books ("title", "public_id") VALUES('Ruby CookBook', 1) => true rails对ruby的类加载机制作了增强,引用The rails way上的解释: 引用 • If the class or module is not nested, insert an underscore between the constant’s names and require a file of this name. For example: • EstimationCalculator becomes require ‘estimation_calculator’ • KittTurboBoost becomes require ‘kitt_turbo_boost’ • If the class or module is nested, Rails inserts an underscore between each of the containing modules and requires a file in the corresponding set of subdirectories. For example: • MacGyver::SwissArmyKnife becomes require ‘mac_gyver/swiss_army_knife’ • Some::ReallyRatherDeeply::NestedClass becomes require ‘some/ really_rather_deeply/nested_class’ and if not already loaded, Rails would expect to find it in a file called nested_class.rb, in a directory called really_rather_deeply, itself in the directory some of which can be found somewhere in Ruby’s load path (e.g., one of the app subdirectories, lib, or a plu- gin’s lib directory). 其实rails做的比你想像的要多,一旦理解,一切均变得理所当然 |
|
返回顶楼 | |
发表时间:2008-03-01
多谢 lgn21st 的回复.可能是我没有描述明白我的问题吧.我建立的两个model不是在同一个名称空间下的.引用你的例子吧.假如在app/model下面,有两个文件夹,一个是demo1,一个是demo2,现在有两个model
class Demo1::Public < ActiveRecord::Base has_many :books end class Demo2::Book < ActiveRecord::Base belongs_to :public end 不知道又当如何呢? 另外如果我要在controller里面引用这两个model,以下的代码: #test_controller.rb class Test < ApplicationController include Demo1 def index @book = Book.new end end 肯定是错的.但是我又不想把代码写成: @book = Demo1::Book.new 我真的没能弄明白rails到底是怎么搞的. |
|
返回顶楼 | |
发表时间:2008-03-02
能告诉我你为什么不愿意写这样?
@book = Demo1::Book.new 或者实在是对rails的规则不满意,可以操刀改rails的classload的enhance部分吧 |
|
返回顶楼 | |
发表时间:2008-03-02
其实无他,我只是觉得
@book = Demo1::Book.new 这样写有些长而已,我之前一直是搞java的,习惯了import一个包进来,然后就写一个类名. 不管怎么样,多谢lgn21st . |
|
返回顶楼 | |
发表时间:2008-03-02
在Ruby中,类名跟Java中的类名引用机制不同,Ruby的类名其实就是一个constant常量,模块名也是,跟在其他地方定义的常量一样,也就是说,你可以这样写
Book = Demo1::Book @book = Book.new 不过我相信一旦习惯了ruby这种路子以后,就不会在觉得写Demo1::Book.new是很烦的事情了,因为看着直观哪. |
|
返回顶楼 | |
发表时间:2008-03-02
一直对Python,Ruby等语言的源码组织方法没有个好的办法。
因为做实际的项目从Java开始,习惯了Java的源码组织方法,呵呵 |
|
返回顶楼 | |
发表时间:2008-03-03
我测试了,先include module再直接调用module下class是可以的,而且不同位置的同名module可以merge
不过activerecord这个问题估计难以解决,恐怕只能加class_name |
|
返回顶楼 | |