本文为原创。转载请注明:
作者:Utensil
博客: http://blog.csdn.net/utensil/
邮箱: utensilcandel@gmail.com
这两天,在将之前那个基于xml和php的博客网站移植到MySQL和ROR上的过程中,攻克了学习ROR的两个重大难关:
一个是,现在大多数资料讲的都是Rails 1.x中的做法,由于2.x打断了不少向后兼容性(尤其是削去了动态scalffold)
如何在Rails 2.x中做到同样的事情呢?
第二个是如何在Rails框架之外,使用ActiveRecord访问数据库。
这篇文章简单记录我对这些问题的探索成果。要感谢Google,但是要愤慨rdoc的文档形式,以及偶尔有些例子中严重的遗漏!希望它能够越来越完善。
在运行之前,我通过yum安装的包包括:(我是在Fedora 8下,Ruby是)
ruby.i386
ruby-RMagick.i386
ruby-RMagick-doc.i386
ruby-activerecord.noarch
ruby-activesupport.noarch
ruby-cairo.i386
ruby-devel.i386
ruby-docs.i386
ruby-fam.i386
ruby-gdkpixbuf2.i386
ruby-glib2.i386
ruby-irb.i386
ruby-libs.i386
ruby-mysql.i386
ruby-rdoc.i386
ruby-rsvg.i386
ruby-shadow.i386
ruby-sqlite3.i386
rubygem-rake.noarch
rubygems.noarch
加粗了的包较为重要。有些包,看不出直接的用途,是因为Dependency自动装上去的。
Ruby Gem中装了的包有:
actionmailer (2.1.1)
actionpack (2.1.1)
activerecord (2.1.1)
activeresource (2.1.1)
activesupport (2.1.1)
htmlentities (4.0.0)
rails (2.1.1)
rake (0.8.3, 0.7.3)
rubygems-update (1.3.0)
sources (0.0.1)
xml-simple (1.0.11)
第一个问题:(以不用IDE进行讲述,用RadRails的话类似)
cd 你的workspace
rails 你的工程名称
这时会建了一大堆文件夹和文件,如果你手头有介绍Rails的书,他会向你介绍它们的结构的。下文用到的路径,均相对于“你的工程名称”这个文件夹。
cd 你的工程名称
现在可以运行
ruby scripts/server
来启动Ruby内部的服务器,你可以在浏览器访问它报告的那个地址(长得像0.0.0.0:端口号的那个),会看到欢迎界面。
这个时候,你应该去建数据库了,以一个MySQL的数据库SusanBlog为例,假设我们在里面有这样一张表:
CREATE TABLE `blogs` (
`id` int(10) unsigned NOT NULL auto_increment,
`title` varchar(255) NOT NULL,
`ctime` datetime default NULL,
`content` text NOT NULL,
`latestbak` text,
`longetbak` text,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
建完之后,就去修改config/database.yml。很简单易懂,我的yml的Development部分如下:
development:
adapter: mysql
encoding: utf8
database: SusanBlog
username: root
password: root的密码,你自己在MySQL里设的那个
socket: /var/lib/mysql/mysql.sock
要非常注意编码问题,编码不对可能会导致Rails罢工。yml里写的编码要和数据库里的相对应。
yml这一步是scaffold的基石。
接下来可以建立saffold了:
ruby scripts/generate scaffold blog title:varchar ctime:datetime content:text
基本规则是 ruby scripts/generate scaffold 模型名 field:datatype ...
field是你的字段名,datatype是SQL的数据类型。
注意,表名是blogs,是复数,模型名要用单数。假设你的表名是my_items,那么这里写my_item或MyItem都是可以的。
id不用写,自动增加的,不用用户指定。`latestbak` text, `longetbak` text,它们由于不一定要非空,所以不用写。
现在访问localhost:端口号/blogs就会显示数据库中的所有条目,并可以新建,查看,编辑,删除任何一个条目,这就是传说中的CRUD了。
可以修改app/views/blogs/里面的erb模板 (又一个与2.x不同的地方)来改善其界面了,比如我在edit.erb中加入了TinyMCE编辑器:
注意<
%= javascript_include_tag "tinymce/jscripts/tiny_mce/tiny_mce" %
>这一句,这要求你把TinyMCE的文件夹放在public/javascripts下。Rails中对路径的处理有自己的规则,乱放可能会路由不到。
还可以对index进行排序,在app/models/blogs_controler.rb中的index方法(对,没有list方法了)中
把
@blogs = Blog.find(:all)
改成
@blogs = Blog.find(:all, :order => "id DESC")
遗憾的是分页功能(paginate)被删除了,好像有第三方库来做,暂时还没用过。
第二个问题,索性直接用例子讲了,这是我将之前那个xml转进MySQL的脚本
写这个脚本真是千辛万苦,文档太不完善了。注意b.save那一句,文档中没有讲改完了值还要save,后来经过艰辛的探索才发现要这样。
使用REXML真是一种痛苦的经历,建议大家还是用XMLSimple吧,在php里用的就是它,爽死了。
不过我安装了xml-simple之后死活require不到,只好自己到/usr/lib/ruby/gem下面把xmlsimple.rb拿出来放在自己脚本旁边才能用。:( 接下来试试传说中的Hpricot,似乎更加好。
把这些探索的成果贴出来,希望能方便大家少走弯路。
重大发现:
原来require所有用gems装的库在require之前都必须:
一瞬间,好多东西都能用了。那都没说过啊,直到Hpricot的主页上,才有这样的区分(直接用yum安装的不用这一步,而用gem装的则必须。)
作者:Utensil
博客: http://blog.csdn.net/utensil/
邮箱: utensilcandel@gmail.com
这两天,在将之前那个基于xml和php的博客网站移植到MySQL和ROR上的过程中,攻克了学习ROR的两个重大难关:
一个是,现在大多数资料讲的都是Rails 1.x中的做法,由于2.x打断了不少向后兼容性(尤其是削去了动态scalffold)
如何在Rails 2.x中做到同样的事情呢?
第二个是如何在Rails框架之外,使用ActiveRecord访问数据库。
这篇文章简单记录我对这些问题的探索成果。要感谢Google,但是要愤慨rdoc的文档形式,以及偶尔有些例子中严重的遗漏!希望它能够越来越完善。
在运行之前,我通过yum安装的包包括:(我是在Fedora 8下,Ruby是)
ruby.i386
ruby-RMagick.i386
ruby-RMagick-doc.i386
ruby-activerecord.noarch
ruby-activesupport.noarch
ruby-cairo.i386
ruby-devel.i386
ruby-docs.i386
ruby-fam.i386
ruby-gdkpixbuf2.i386
ruby-glib2.i386
ruby-irb.i386
ruby-libs.i386
ruby-mysql.i386
ruby-rdoc.i386
ruby-rsvg.i386
ruby-shadow.i386
ruby-sqlite3.i386
rubygem-rake.noarch
rubygems.noarch
加粗了的包较为重要。有些包,看不出直接的用途,是因为Dependency自动装上去的。
Ruby Gem中装了的包有:
actionmailer (2.1.1)
actionpack (2.1.1)
activerecord (2.1.1)
activeresource (2.1.1)
activesupport (2.1.1)
htmlentities (4.0.0)
rails (2.1.1)
rake (0.8.3, 0.7.3)
rubygems-update (1.3.0)
sources (0.0.1)
xml-simple (1.0.11)
第一个问题:(以不用IDE进行讲述,用RadRails的话类似)
cd 你的workspace
rails 你的工程名称
这时会建了一大堆文件夹和文件,如果你手头有介绍Rails的书,他会向你介绍它们的结构的。下文用到的路径,均相对于“你的工程名称”这个文件夹。
cd 你的工程名称
现在可以运行
ruby scripts/server
来启动Ruby内部的服务器,你可以在浏览器访问它报告的那个地址(长得像0.0.0.0:端口号的那个),会看到欢迎界面。
这个时候,你应该去建数据库了,以一个MySQL的数据库SusanBlog为例,假设我们在里面有这样一张表:
CREATE TABLE `blogs` (
`id` int(10) unsigned NOT NULL auto_increment,
`title` varchar(255) NOT NULL,
`ctime` datetime default NULL,
`content` text NOT NULL,
`latestbak` text,
`longetbak` text,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
建完之后,就去修改config/database.yml。很简单易懂,我的yml的Development部分如下:
development:
adapter: mysql
encoding: utf8
database: SusanBlog
username: root
password: root的密码,你自己在MySQL里设的那个
socket: /var/lib/mysql/mysql.sock
要非常注意编码问题,编码不对可能会导致Rails罢工。yml里写的编码要和数据库里的相对应。
yml这一步是scaffold的基石。
接下来可以建立saffold了:
ruby scripts/generate scaffold blog title:varchar ctime:datetime content:text
基本规则是 ruby scripts/generate scaffold 模型名 field:datatype ...
field是你的字段名,datatype是SQL的数据类型。
注意,表名是blogs,是复数,模型名要用单数。假设你的表名是my_items,那么这里写my_item或MyItem都是可以的。
id不用写,自动增加的,不用用户指定。`latestbak` text, `longetbak` text,它们由于不一定要非空,所以不用写。
现在访问localhost:端口号/blogs就会显示数据库中的所有条目,并可以新建,查看,编辑,删除任何一个条目,这就是传说中的CRUD了。
可以修改app/views/blogs/里面的erb模板 (又一个与2.x不同的地方)来改善其界面了,比如我在edit.erb中加入了TinyMCE编辑器:
- <h1>编辑日志</h1>
- <%= link_to 'Show', @blog %> |
- <%= link_to 'Back', blogs_path %>
- <% form_for(@blog) do |f| %>
- <%= f.error_messages %>
- <p>
- <%= f.label :title %><br />
- <%= f.text_field :title %>
- </p>
- <p>
- <%= f.label :ctime %><br />
- <%= f.datetime_select :ctime %>
- </p>
- <!-- TinyMCE -->
- <%= javascript_include_tag "tinymce/jscripts/tiny_mce/tiny_mce" %>
- <script type="text/javascript">
- tinyMCE.init({
- // General options
- mode : "textareas",
- theme : "advanced",
- skin : "o2k7",
- plugins : "safari,style,table,save,advhr,advimage,advlink,emotions,inlinepopups,insertdatetime,preview,searchreplace,contextmenu,paste,directionality,fullscreen,visualchars,nonbreaking,xhtmlxtras",
- editor_deselector : "mceNoEditor",
- // Theme options
- theme_advanced_buttons1 : "save,|,undo,redo,|,cut,copy,paste,pastetext,pasteword,|,search,replace,|,formatselect,fontselect,fontsizeselect,styleselect",
- theme_advanced_buttons2 : "bold,italic,underline,strikethrough,|,hr,|,sub,sup,|,justifyleft,justifycenter,justifyright,justifyfull,|,bullist,numlist,|,outdent,indent,blockquote,|,forecolor,backcolor,styleprops,|,removeformat,cleanup",
- theme_advanced_buttons3 : "link,unlink,image,charmap,emotions,|,insertdate,inserttime,|,tablecontrols,|,visualaid,visualchars,|,fullscreen,code,preview",
- theme_advanced_toolbar_location : "top",
- theme_advanced_toolbar_align : "left",
- theme_advanced_statusbar_location : "bottom",
- theme_advanced_resizing : true,
- // Example content CSS (should be your site CSS)
- content_css : "css/content.css",
- });
- </script>
- <!-- /TinyMCE -->
- <p>
- <%= f.label :content %><br />
- <%= f.text_area :content,:id=>'elm1'%>
- </p>
- <p>
- <%= f.submit "Update" %>
- </p>
- <% end %>
还可以对index进行排序,在app/models/blogs_controler.rb中的index方法(对,没有list方法了)中
把
@blogs = Blog.find(:all)
改成
@blogs = Blog.find(:all, :order => "id DESC")
遗憾的是分页功能(paginate)被删除了,好像有第三方库来做,暂时还没用过。
第二个问题,索性直接用例子讲了,这是我将之前那个xml转进MySQL的脚本
- #!/usr/bin/ruby
- require "rexml/document"
- require "active_record"
- ActiveRecord::Base.establish_connection(
- :adapter => "mysql",
- :username => "user",
- :password => "password",
- :database => "SusanBlog",
- :host => "localhost",
- :encoding => "utf8"
- )
- class Blog < ActiveRecord::Base
- end
- file = File.new "./susanblog_original.xml"
- blogs = REXML::Document.new file
- #也可以用blogs.elements.each("blogs/blog") do |e|,但我需要把整个顺序倒过来
- ordered = blogs.get_elements("blogs/blog").reverse!
- ordered.each do |e|
- Blog.new do |b|
- b.title = e.get_text("title").to_s
- b.ctime = e.get_text("timestamp").to_s #or we can use Time.now.strftime "%Y-%m-%d %H:%M:%S"
- b.content = e.get_text("content").to_s
- b.save
- end
- end
使用REXML真是一种痛苦的经历,建议大家还是用XMLSimple吧,在php里用的就是它,爽死了。
不过我安装了xml-simple之后死活require不到,只好自己到/usr/lib/ruby/gem下面把xmlsimple.rb拿出来放在自己脚本旁边才能用。:( 接下来试试传说中的Hpricot,似乎更加好。
把这些探索的成果贴出来,希望能方便大家少走弯路。
重大发现:
原来require所有用gems装的库在require之前都必须:
- require 'rubygems'