CSDN博客

img Utensil

Ruby on Rails 2.x实践手记

发表于2008/10/2 10:11:00  1381人阅读

分类: Web

本文为原创。转载请注明:
作者: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编辑器:

  1. <h1>编辑日志</h1>
  2. <%= link_to 'Show', @blog %> |
  3. <%= link_to 'Back', blogs_path %>
  4. <% form_for(@blog) do |f| %>
  5.   <%= f.error_messages %>
  6.   <p>
  7.     <%= f.label :title %><br />
  8.     <%= f.text_field :title %>
  9.   </p>
  10.   <p>
  11.     <%= f.label :ctime %><br />
  12.     <%= f.datetime_select :ctime %>
  13.   </p>
  14.   
  15. <!-- TinyMCE -->
  16. <%= javascript_include_tag "tinymce/jscripts/tiny_mce/tiny_mce" %>
  17. <script type="text/javascript">
  18.     tinyMCE.init({
  19.         // General options
  20.         mode : "textareas",
  21.         theme : "advanced",
  22.         skin : "o2k7",
  23.         plugins : "safari,style,table,save,advhr,advimage,advlink,emotions,inlinepopups,insertdatetime,preview,searchreplace,contextmenu,paste,directionality,fullscreen,visualchars,nonbreaking,xhtmlxtras",
  24.         editor_deselector : "mceNoEditor",
  25.         // Theme options
  26.         theme_advanced_buttons1 : "save,|,undo,redo,|,cut,copy,paste,pastetext,pasteword,|,search,replace,|,formatselect,fontselect,fontsizeselect,styleselect",
  27.         theme_advanced_buttons2 : "bold,italic,underline,strikethrough,|,hr,|,sub,sup,|,justifyleft,justifycenter,justifyright,justifyfull,|,bullist,numlist,|,outdent,indent,blockquote,|,forecolor,backcolor,styleprops,|,removeformat,cleanup",
  28.         theme_advanced_buttons3 : "link,unlink,image,charmap,emotions,|,insertdate,inserttime,|,tablecontrols,|,visualaid,visualchars,|,fullscreen,code,preview",
  29.         theme_advanced_toolbar_location : "top",
  30.         theme_advanced_toolbar_align : "left",
  31.         theme_advanced_statusbar_location : "bottom",
  32.         theme_advanced_resizing : true,
  33.         // Example content CSS (should be your site CSS)
  34.         content_css : "css/content.css",
  35.     });
  36. </script>
  37. <!-- /TinyMCE -->
  38.   
  39.   <p>
  40.     <%= f.label :content %><br />
  41.     <%= f.text_area :content,:id=>'elm1'%>
  42.   </p>
  43.   <p>
  44.     <%= f.submit "Update" %>
  45.   </p>
  46. <% end %>

注意<%= 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的脚本

  1. #!/usr/bin/ruby

  2. require "rexml/document"

  3. require "active_record"

  4. ActiveRecord::Base.establish_connection(
  5. :adapter => "mysql",
  6. :username => "user",
  7. :password => "password",
  8. :database => "SusanBlog",
  9. :host => "localhost",
  10. :encoding => "utf8"
  11. )

  12. class Blog < ActiveRecord::Base
  13. end

  14. file = File.new "./susanblog_original.xml"
  15. blogs = REXML::Document.new file

  16. #也可以用blogs.elements.each("blogs/blog") do |e|,但我需要把整个顺序倒过来

  17. ordered = blogs.get_elements("blogs/blog").reverse!

  18. ordered.each do |e|
  19.   Blog.new do |b|
  20.     
  21.     b.title = e.get_text("title").to_s
  22.     b.ctime = e.get_text("timestamp").to_s     #or we can use Time.now.strftime "%Y-%m-%d %H:%M:%S"
  23.     b.content = e.get_text("content").to_s
  24.     
  25.     b.save
  26.   end
  27.   
  28. end
写这个脚本真是千辛万苦,文档太不完善了。注意b.save那一句,文档中没有讲改完了值还要save,后来经过艰辛的探索才发现要这样。

使用REXML真是一种痛苦的经历,建议大家还是用XMLSimple吧,在php里用的就是它,爽死了。

不过我安装了xml-simple之后死活require不到,只好自己到/usr/lib/ruby/gem下面把xmlsimple.rb拿出来放在自己脚本旁边才能用。:( 接下来试试传说中的Hpricot,似乎更加好。

把这些探索的成果贴出来,希望能方便大家少走弯路。

重大发现:

原来require所有用gems装的库在require之前都必须:
  1. require 'rubygems'
一瞬间,好多东西都能用了。那都没说过啊,直到Hpricot的主页上,才有这样的区分(直接用yum安装的不用这一步,而用gem装的则必须。)







0 0

相关博文

我的热门文章

img
取 消
img