基于Ruby on Rails的论坛实现(新手指南)

用Rails实现一个简单的论坛系统,大致的架构为:站点拥有多个Forum,每个Forum有多个Topic,而每个Topic又有多个Reply。原文链接: http://railsonedge.blogspot.com/2008/02/rails-forum-tutorial-for-beginners-part.html

我下载的是目前最新的Rails版本2.1,数据库使用的是Sql Server 2000,应用程序所在目录为F:\Ruby\railsdoc\myforum。首先快速地依照以下步骤创建Forum类:

  1. 执行rails myforum生成完整的目录结构;
  2. 执行ruby script/generate scaffold Forum name:string description:text创建相关的数据库移植文件及model、controller、views文件;
  3. 修改database.yml文件中的相关数据库配置信息;
  4. 在Sql Server中新建名为myforum的数据库,并执行rake db:migrate创建forums表;
  5. 修改environment.rb文件使页面能正常显示中文。
这样Forum页面就完成了,启动服务器后在浏览器键入http://127.0.0.1:3000/forums便能进行CRUD操作了。

删除/public/index.html,修改/config/routes.rb,使得http://localhost:3000直接指向Forum列表:
引用
map.root :controller => 'forums', :action => 'index'


分别执行以下命令创建Topic和Reply的相关文件及数据库表:
引用
ruby script/generate scaffold Topic forum:references user:references subject:string body:text

ruby script/generate scaffold Reply topic:references user:references subject:string body:text

rake db:migrate


表Forum


表Topic


表Reply


修改/config/routes.rb
……
map.resources :forums, :has_many => :topics  # Add
map.resources :topics, :has_many => :replies  # Add
map.resources :replies
…… 


修改/app/models/forum.rb
class Forum < ActiveRecord::Base
  has_many :topics  # Add
  has_many :replies, :through => :topics  # Add
end


修改/app/models/topic.rb
class Topic < ActiveRecord::Base
  belongs_to :forum  # Add
  belongs_to :user  # Add
  has_many :replies  # Add
end


修改/app/models/reply.rb
class Reply < ActiveRecord::Base
  belongs_to :topic  # Add
  belongs_to :user  # Add
end


修改/app/controllers/topics_controller.rb
class TopicsController < ApplicationController
  before_filter :load_forum  # Add
 
  def load_forum  # Add
    @forum = Forum.find(params[:forum_id])  # Add
  end  # Add

  # GET /topics
  # GET /topics.xml
  def index
   @topics = @forum.topics  # Edit: @topics = Topic.find(:all)

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @topics }
    end
  end

  # GET /topics/1
  # GET /topics/1.xml
  def show
   @topic = @forum.topics.find(params[:id])  # Edit: @topic = Topic.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @topic }
    end
  end

  # GET /topics/new
  # GET /topics/new.xml
  def new
   @topic = @forum.topics.build  # Edit: @topic = Topic.new

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @topic }
    end
  end

  # GET /topics/1/edit
  def edit
   @topic = @forum.topics.find(params[:id])  # Edit: @topic = Topic.find(params[:id])
  end

  # POST /topics
  # POST /topics.xml
  def create
   @topic = @forum.topics.build(params[:topic])  # Edit: @topic = Topic.new(params[:topic])

    respond_to do |format|
      if @topic.save
        flash[:notice] = 'Topic was successfully created.'
       format.html { redirect_to(@forum) }  # Edit: format.html { redirect_to(@topic) }
        format.xml  { render :xml => @topic, :status => :created, :location => @topic }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @topic.errors, :status => :unprocessable_entity }
      end
    end
  end

  # PUT /topics/1
  # PUT /topics/1.xml
  def update
   @topic = @forum.topics.find(params[:id])  # Edit: @topic = Topic.find(params[:id])

    respond_to do |format|
      if @topic.update_attributes(params[:topic])
        flash[:notice] = 'Topic was successfully updated.'
       format.html { redirect_to(@forum) }  # Edit: format.html { redirect_to(@topic) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @topic.errors, :status => :unprocessable_entity }
      end
    end
  end

  # DELETE /topics/1
  # DELETE /topics/1.xml
  def destroy
   @topic = @forum.topics.find(params[:id])  # Edit: @topic = Topic.find(params[:id])
    @topic.destroy

    respond_to do |format|
     format.html { redirect_to(forum_topics_url(@forum)) }  # Edit: format.html { redirect_to(topics_url) }
      format.xml  { head :ok }
    end
  end
end


以上修改基于两个目的:一、使得对于Topic的操作能关联到正确的外键(forum_id),二、在对Topic执行CUD操作后将能返回至相应的Forum页面,而不是Topic页面。

将/app/views/forums/show.html.erb
<p>
  <b>Name:</b>
  <%=h @forum.name %>
</p>

<p>
  <b>Description:</b>
  <%=h @forum.description %>
</p>


<%= link_to 'Edit', edit_forum_path(@forum) %> |
<%= link_to 'Back', forums_path %>

修改为
<p>
  <b>Forum:</b>
  <%=h @forum.name %> - <%=h @forum.description %>
</p>

<% unless @forum.topics.empty? %>
  <h2>Topics</h2>
  <% @forum.topics.each do |topic| %>
    <b><%= link_to topic.subject, [@forum, topic] %></b><br />    
  <% end %>
<% end %>

<h2>New Post</h2>
<%= render :partial => @topic = Topic.new, :locals => { :button_name => 'Create' } %>

<%= link_to 'Edit', edit_forum_path(@forum) %> |
<%= link_to 'Back', forums_path %>


可以看到/app/views/topics/new.html.erb和/app/views/topics/edit.html.erb相当类似,我们创建一个新的文件/app/views/topics/_topic.html.erb
<% form_for([@forum, @topic]) do |f| %>
  <p>
    <b>Subject</b><br />
    <%= f.text_field :subject %>
  </p>

  <p>
    <b>Body</b><br />
    <%= f.text_area :body %>
  </p>

  <p>
    <%= f.submit button_name %>
  </p>
<% end %>


将/app/views/topics/new.html.erb
<h1>New topic</h1>

<% form_for(@topic) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :forum %><br />
    <%= f.text_field :forum %>
  </p>
  <p>
    <%= f.label :user %><br />
    <%= f.text_field :user %>
  </p>
  <p>
    <%= f.label :subject %><br />
    <%= f.text_field :subject %>
  </p>
  <p>
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.submit "Create" %>
  </p>
<% end %>

<%= link_to 'Back', topics_path %>

修改为
<h1>New topic</h1>

<%= error_messages_for :topic %>

<%= render :partial => @topic, :locals => { :button_name => "Create" } %>

<%= link_to 'Back', topics_path %>


将/app/views/topics/edit.html.erb
<h1>Editing topic</h1>

<% form_for(@topic) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :forum %><br />
    <%= f.text_field :forum %>
  </p>
  <p>
    <%= f.label :user %><br />
    <%= f.text_field :user %>
  </p>
  <p>
    <%= f.label :subject %><br />
    <%= f.text_field :subject %>
  </p>
  <p>
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.submit "Update" %>
  </p>
<% end %>

<%= link_to 'Show', @topic %> |
<%= link_to 'Back', topics_path %>

修改为
<h1>Editing topic</h1>

<%= error_messages_for :topic %>

<%= render :partial => @topic, :locals => { :button_name => "Submit" } %>

<%= link_to 'Show', [@forum, @topic] %> |
<%= link_to 'Back', topics_path %>


目前部分已完成Forum和Topic的关联,以下是操作页面截图:
Forum List


Topic List


Topic Details

你可能感兴趣的:(xml,F#,Ruby,Rails,ActiveRecord)