<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>weskycn</title>
    <description>七哥</description>
    <link>http://weskycn.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>Gem 可以像插件一样unpack到vendor/gems/目录了！</title>
        <author>weskycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://weskycn.javaeye.com">weskycn</a>&nbsp;
          链接：<a href="http://weskycn.javaeye.com/blog/178730" style="color:red;">http://weskycn.javaeye.com/blog/178730</a>&nbsp;
          发表时间: 2008年04月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          用虚拟主机的朋友要舒服了<br />http://dev.rubyonrails.org/changeset/9140
          <br/>
          <span style="color:red;">
            <a href="http://weskycn.javaeye.com/blog/178730#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 02 Apr 2008 11:06:22 +0800</pubDate>
        <link>http://weskycn.javaeye.com/blog/178730</link>
        <guid>http://weskycn.javaeye.com/blog/178730</guid>
      </item>
      <item>
        <title>Rails Messaging Tutorial</title>
        <author>weskycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://weskycn.javaeye.com">weskycn</a>&nbsp;
          链接：<a href="http://weskycn.javaeye.com/blog/164318" style="color:red;">http://weskycn.javaeye.com/blog/164318</a>&nbsp;
          发表时间: 2008年02月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://www.novawave.net/public/rails_messaging_tutorial.html" target="_blank">http://www.novawave.net/public/rails_messaging_tutorial.html</a>
          <br/>
          <span style="color:red;">
            <a href="http://weskycn.javaeye.com/blog/164318#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 22 Feb 2008 17:34:02 +0800</pubDate>
        <link>http://weskycn.javaeye.com/blog/164318</link>
        <guid>http://weskycn.javaeye.com/blog/164318</guid>
      </item>
      <item>
        <title>学习Ruport</title>
        <author>weskycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://weskycn.javaeye.com">weskycn</a>&nbsp;
          链接：<a href="http://weskycn.javaeye.com/blog/162528" style="color:red;">http://weskycn.javaeye.com/blog/162528</a>&nbsp;
          发表时间: 2008年02月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://ruportbook.com/">http://ruportbook.com/</a>
          <br/>
          <span style="color:red;">
            <a href="http://weskycn.javaeye.com/blog/162528#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 15 Feb 2008 17:13:14 +0800</pubDate>
        <link>http://weskycn.javaeye.com/blog/162528</link>
        <guid>http://weskycn.javaeye.com/blog/162528</guid>
      </item>
      <item>
        <title>ActiveResource探究（二）－－多用户的客户端</title>
        <author>weskycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://weskycn.javaeye.com">weskycn</a>&nbsp;
          链接：<a href="http://weskycn.javaeye.com/blog/162276" style="color:red;">http://weskycn.javaeye.com/blog/162276</a>&nbsp;
          发表时间: 2008年02月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>在前面的教程（<a href="../../../blog/156675">ActiveResource探究（一）</a>）中，在服务器端每个用户都很直接，但是处理多用户的时候就会遇到麻烦，假如我有两个servers，一个处理REAST service，另一个处理html文件。但是ActiveResource假设认证实在类的层面上处理。这个时候ruby的元编程思想可以解决问题！</p><p>&nbsp;</p><p>使用前面的例子，我扩展客户端如下：</p><div class="typocode"><pre><span class="ident">require</span> <span class="punct">'</span><span class="string">activeresource</span><span class="punct">'</span>

<span class="keyword">module </span><span class="module">Sample</span>
  <span class="keyword">module </span><span class="module">Client</span>
    <span class="keyword">class </span><span class="class">API</span>
      <span class="comment">#</span>
      <span class="comment"># Creates a module that serves as an ActiveResource</span>
      <span class="comment"># client for the specified user</span>
      <span class="comment">#</span>
      <span class="keyword">def </span><span class="method">self.create_api</span><span class="punct">(</span><span class="ident">login</span> <span class="punct">=</span> <span class="constant">nil</span><span class="punct">,</span> <span class="ident">password</span> <span class="punct">=</span> <span class="constant">nil</span><span class="punct">)</span>
        <span class="comment"># specify the site.  Default to no credentials</span>
        <span class="attribute">@url_base</span> <span class="punct">=</span> <span class="punct">&quot;</span><span class="string">http://localhost:3000</span><span class="punct">&quot;</span>
        <span class="attribute">@url_base</span> <span class="punct">=</span> <span class="punct">&quot;</span><span class="string">http://<span class="expr">#{login}</span>:<span class="expr">#{password}</span>@localhost:3000</span><span class="punct">&quot;</span> <span class="keyword">if</span> <span class="ident">login</span>
        <span class="comment"># build a module name.  This assumes that logins are unique.</span>
        <span class="comment"># it also assumes they're valid ruby module names when capitalized</span>
        <span class="attribute">@module</span> <span class="punct">=</span> <span class="ident">login</span> <span class="punct">?</span> <span class="ident">login</span><span class="punct">.</span><span class="ident">capitalize</span> <span class="punct">:</span> <span class="punct">&quot;</span><span class="string">Default</span><span class="punct">&quot;</span>
        <span class="ident">class_eval</span> <span class="punct">&lt;&lt;-&quot;</span><span class="constant">end_eval</span><span class="punct">&quot;,</span><span class="constant">__FILE__</span><span class="punct">,</span> <span class="constant">__LINE__</span><span class="string">
        module <span class="expr">#{@module}</span>
          class Post &lt; ActiveResource::Base
            self.site = &quot;<span class="expr">#{@url_base}</span>&quot;
          end
          class Comment &lt; ActiveResource::Base
            self.site = &quot;<span class="expr">#{@url_base}</span>/posts/:post_id&quot;
          end
          # return the module, not the last site String
          self
        end
</span><span class="constant">        end_eval</span>
      <span class="keyword">end</span>
    <span class="keyword">end</span>
  <span class="keyword">end</span>
<span class="keyword">end</span></pre></div><p>&nbsp;</p><p>&nbsp;</p><p>这次允许我们为特定的用户创建特定的api，这样多个用户都可以链接到rest service了，来看看吧：</p><div class="typocode"><pre>&gt;&gt; require 'ares_sample_client'
=&gt; [&quot;Sample&quot;]
&gt;&gt; api = Sample::Client::API.create_api
=&gt; Sample::Client::API::Default
&gt;&gt; p = api::Post.find(1)
=&gt; #&lt;Sample::Client::API::Default::Post:0xb715af74 @attributes={&quot;updated_at&quot;=&gt;Wed Jan 09 02:36:34 UTC 2008, &quot;id&quot;=&gt;1, &quot;content&quot;=&gt;&quot;The first post&quot;, &quot;user_id&quot;=&gt;1, &quot;created_at&quot;=&gt;Wed Jan 09 02:36:34 UTC 2008}, @prefix_options={}&gt;
&gt;&gt; p = api::Post.create(:content =&gt; &quot;should fail&quot;)
ActiveResource::UnauthorizedAccess: Failed with 401 Unauthorized
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/connection.rb:125:in `handle_response'
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/connection.rb:112:in `request'
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/connection.rb:101:in `post'
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/base.rb:803:in `create'
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/base.rb:636:in `save_without_validation'
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/validations.rb:262:in `save'
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/base.rb:339:in `create'
        from /usr/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/core_ext/object/misc.rb:28:in `returning'
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/base.rb:339:in `create'
        from (irb):4
&gt;&gt; auth_api = Sample::Client::API.create_api('test1','test1')
=&gt; Sample::Client::API::Test1
&gt;&gt; p = auth_api::Post.find(1)
=&gt; #&lt;Sample::Client::API::Default::Post:0xb713dde8 @attributes={&quot;updated_at&quot;=&gt;Wed Jan 09 02:36:34 UTC 2008, &quot;id&quot;=&gt;1, &quot;content&quot;=&gt;&quot;The first post&quot;, &quot;user_id&quot;=&gt;1, &quot;created_at&quot;=&gt;Wed Jan 09 02:36:34 UTC 2008}, @prefix_options={}&gt;
&gt;&gt; p = auth_api::Post.create(:content =&gt; &quot;should succeed!&quot;)
=&gt; #&lt;Sample::Client::API::Test1::Post:0xb713312c @attributes={&quot;updated_at&quot;=&gt;Thu Jan 10 04:01:53 UTC 2008, &quot;id&quot;=&gt;7, &quot;content&quot;=&gt;&quot;should succeed!&quot;, &quot;user_id&quot;=&gt;nil, &quot;created_at&quot;=&gt;Thu Jan 10 04:01:53 UTC 2008}, @prefix_options={}&gt;
&gt;&gt;</pre></div>
          <br/>
          <span style="color:red;">
            <a href="http://weskycn.javaeye.com/blog/162276#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 14 Feb 2008 17:03:06 +0800</pubDate>
        <link>http://weskycn.javaeye.com/blog/162276</link>
        <guid>http://weskycn.javaeye.com/blog/162276</guid>
      </item>
      <item>
        <title>ActiveResource探究（一）－－跑起来再说</title>
        <author>weskycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://weskycn.javaeye.com">weskycn</a>&nbsp;
          链接：<a href="http://weskycn.javaeye.com/blog/156675" style="color:red;">http://weskycn.javaeye.com/blog/156675</a>&nbsp;
          发表时间: 2008年01月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <h2>ActiveResource探究<span style="color: #000000">一</span></h2><p class="auth">&nbsp;</p><p>本教程向大家展示使用ActiveResource创建简单的REST风格的API。包括两个嵌套得Model、认证和客户端。目的是快速地搭建一个可用的REST API。</p><p>&nbsp;</p><p><span style="font-size: medium; color: #000000"><strong>步骤一：新建一个项目</strong></span></p><div class="typocode"><pre>rails ares-demo</pre></div><p>使用rails 2.0.2版本，我想这与版本无关。</p><p>&nbsp;</p><p><span style="font-size: medium"><strong>步骤二：安装两个好用的插件</strong></span></p><p>&nbsp;</p><p><a href="http://soylentfoo.jnewland.com/articles/2007/09/17/resource_this-dry-rails-resource-controllers">Resource This</a>插件会将默认rest风格的action加到controller上。并且支持多层资源嵌套...通过下面的命令安装：</p><div class="typocode"><pre>script/plugin install http://jnewland.com/svn/public/ruby/rails/plugins/resource_this/</pre></div><p>&nbsp;</p><p><a href="http://agilewebdevelopment.com/plugins/restful_authentication">Restful Authentication</a>众所周知是一个认证插件，通过下面的命令安装：</p><div class="typocode"><pre>script/plugin install http://svn.techno-weenie.net/projects/plugins/restful_authentication/</pre></div><p>&nbsp;</p><p><span style="font-size: medium"><strong>步骤三：设置restful authentication</strong></span></p><p>&nbsp;</p><p>非常简单，使用生成器生成migrations还有其他一些东西，具体用法请搜索restful authentication的用法指导</p><div class="typocode"><pre>./script/generate authenticated user sessions</pre></div><p>&nbsp;</p><p><span style="font-size: medium"><strong>步骤四：生成程序Model</strong></span></p><p>&nbsp;</p><p>接下来就是生成你的model了。我门做一个简单的，posts包括很多comments，posts和comments都属于user，命令如下：</p><div class="typocode"><pre>./script/generate scaffold posts
./script/generate scaffold comments</pre></div><p>下面修改migration文件，如下：</p><p>db/migrate/002_create_posts.rb </p><div class="typocode"><pre><span class="keyword">class </span><span class="class">CreatePosts</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Migration</span>
  <span class="keyword">def </span><span class="method">self.up</span>
    <span class="ident">create_table</span> <span class="symbol">:posts</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">t</span><span class="punct">|</span>
      <span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:content</span><span class="punct">,</span> <span class="symbol">:text</span>
      <span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:user_id</span><span class="punct">,</span> <span class="symbol">:integer</span>
      <span class="ident">t</span><span class="punct">.</span><span class="ident">timestamps</span>
    <span class="keyword">end</span>
  <span class="keyword">end</span>

  <span class="keyword">def </span><span class="method">self.down</span>
    <span class="ident">drop_table</span> <span class="symbol">:posts</span>
  <span class="keyword">end</span>
<span class="keyword">end</span></pre></div><p>db/migrate/003_create_comments.rb </p><div class="typocode"><pre><span class="keyword">class </span><span class="class">CreateComments</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Migration</span>
  <span class="keyword">def </span><span class="method">self.up</span>
    <span class="ident">create_table</span> <span class="symbol">:comments</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">t</span><span class="punct">|</span>
      <span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:content</span><span class="punct">,</span> <span class="symbol">:text</span>
      <span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:user_id</span><span class="punct">,</span> <span class="symbol">:integer</span>
      <span class="ident">t</span><span class="punct">.</span><span class="ident">column</span> <span class="symbol">:post_id</span><span class="punct">,</span> <span class="symbol">:integer</span>
      <span class="ident">t</span><span class="punct">.</span><span class="ident">timestamps</span>
    <span class="keyword">end</span>
  <span class="keyword">end</span>

  <span class="keyword">def </span><span class="method">self.down</span>
    <span class="ident">drop_table</span> <span class="symbol">:comments</span>
  <span class="keyword">end</span>
<span class="keyword">end</span></pre></div><p>Next you'll need to add the relationships to your model classes. Add the following bit to the front of app/models/user.rb </p><p>下一步给这三个模型加上关联：</p><div class="typocode"><pre><span class="keyword">class </span><span class="class">User</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
  <span class="comment"># custom relationships</span>
  <span class="ident">has_many</span> <span class="symbol">:posts</span>
  <span class="ident">has_many</span> <span class="symbol">:comments</span></pre></div><p>app/models/post.rb </p><div class="typocode"><pre><span class="keyword">class </span><span class="class">Post</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
  <span class="ident">belongs_to</span> <span class="symbol">:user</span>
  <span class="ident">has_many</span> <span class="symbol">:comments</span>
<span class="keyword">end</span></pre></div><p>and app/models/comment.rb </p><div class="typocode"><pre><span class="keyword">class </span><span class="class">Comment</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
  <span class="ident">belongs_to</span> <span class="symbol">:user</span>
  <span class="ident">belongs_to</span> <span class="symbol">:post</span>
<span class="keyword">end</span></pre></div><p>用下面命令生成数据库：</p><p>&nbsp;</p><div class="typocode"><pre>rake db:migrate</pre></div><p>&nbsp;</p><p><span style="font-size: medium"><strong>步骤五：装载测试数据</strong></span></p><p>&nbsp;</p><p>添加一些默认数据，执行命令script/console,如下：</p><div class="typocode"><pre>&gt;&gt; u1 = User.new(:login =&gt; &quot;test1&quot;, :email =&gt; &quot;test1@foo.com&quot;, :password =&gt; &quot;test1&quot;, :password_confirmation =&gt; &quot;test1&quot;)
=&gt; #&lt;User id: nil, login: &quot;test1&quot;, email: &quot;test1@foo.com&quot;, crypted_password: nil, salt: nil, created_at: nil, updated_at: nil, remember_token: nil, remember_token_expires_at: nil&gt;
&gt;&gt; u1.save
=&gt; true
&gt;&gt; u2 = User.new(:login =&gt; &quot;test2&quot;, :email =&gt; &quot;test2@foo.com&quot;, :password =&gt; &quot;test2&quot;, :password_confirmation =&gt; &quot;test2&quot;)
=&gt; #&lt;User id: nil, login: &quot;test2&quot;, email: &quot;test2@foo.com&quot;, crypted_password: nil, salt: nil, created_at: nil, updated_at: nil, remember_token: nil, remember_token_expires_at: nil&gt;
&gt;&gt; u2.save
=&gt; true
&gt;&gt; p = Post.new(:user =&gt; u1, :content =&gt; &quot;The first post&quot;)
=&gt; #&lt;Post id: nil, content: &quot;The first post&quot;, user_id: 1, created_at: nil, updated_at: nil&gt;
&gt;&gt; p.save
=&gt; true
&gt;&gt; c = Comment.new(:user =&gt; u2, :post =&gt; p, :content =&gt; &quot;first!&quot;)
=&gt; #&lt;Comment id: nil, content: &quot;first!&quot;, user_id: 2, post_id: 1, created_at: nil, updated_at: nil&gt;
&gt;&gt; c.save
=&gt; true
&gt;&gt;</pre></div><p>&nbsp;</p><p><span style="font-size: medium"><strong>步骤六：resource_this!</strong></span></p><p>&nbsp;</p><p>接下来我们用插件resource_this!修改如下文件app/controllers/posts_controller.rb </p><div class="typocode"><pre><span class="keyword">class </span><span class="class">PostsController</span> <span class="punct">&lt;</span> <span class="constant">ApplicationController</span>
  <span class="ident">resource_this</span>
<span class="keyword">end</span></pre></div><p>app/controllers/comments_controller.rb </p><p>&nbsp;</p><div class="typocode"><pre><span class="keyword">class </span><span class="class">CommentsController</span> <span class="punct">&lt;</span> <span class="constant">ApplicationController</span>
  <span class="ident">resource_this</span> <span class="symbol">:nested</span> <span class="punct">=&gt;</span> <span class="punct">[</span><span class="symbol">:post</span><span class="punct">]</span>
<span class="keyword">end</span></pre></div><p>And finally update config/routes.rb </p><p>&nbsp;</p><div class="typocode"><pre><span class="constant">ActionController</span><span class="punct">::</span><span class="constant">Routing</span><span class="punct">::</span><span class="constant">Routes</span><span class="punct">.</span><span class="ident">draw</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">map</span><span class="punct">|</span>
  <span class="ident">map</span><span class="punct">.</span><span class="ident">resources</span> <span class="symbol">:posts</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">post</span><span class="punct">|</span>
    <span class="ident">post</span><span class="punct">.</span><span class="ident">resources</span> <span class="symbol">:comments</span>
  <span class="keyword">end</span>

  <span class="ident">map</span><span class="punct">.</span><span class="ident">resources</span> <span class="symbol">:users</span>

  <span class="ident">map</span><span class="punct">.</span><span class="ident">resource</span> <span class="symbol">:session</span>
<span class="keyword">end</span></pre></div><p>就是这样，现在你可以关注你的API了！</p><p>&nbsp;</p><p><span style="font-size: medium"><strong>步骤七：浏览</strong></span></p><p>&nbsp;</p><p>用命令script/server启动网站服务器，访问下面的链接</p><ul><li><a href="http://localhost:3000/posts/1.xml">http://localhost:3000/posts/1.xml</a> </li><li><a href="http://localhost:3000/posts/1/comments.xml">http://localhost:3000/posts/1/comments.xml</a> </li></ul><p>&nbsp;</p><p><span style="font-size: medium"><strong>步骤八：开船</strong></span></p><p>&nbsp;</p><p>到目前为止，我们的service对所有人开放。我们将加入简单的认证，我们将对某些action加以控制：</p><p>修改app/controllers/application.rb </p><div class="typocode"><pre><span class="keyword">class </span><span class="class">ApplicationController</span> <span class="punct">&lt;</span> <span class="constant">ActionController</span><span class="punct">::</span><span class="constant">Base</span>
  <span class="ident">include</span> <span class="constant">AuthenticatedSystem</span>
  <span class="ident">before_filter</span> <span class="symbol">:login_required</span><span class="punct">,</span> <span class="symbol">:only</span> <span class="punct">=&gt;</span> <span class="punct">[</span><span class="symbol">:create</span><span class="punct">,</span><span class="symbol">:edit</span><span class="punct">,</span><span class="symbol">:new</span><span class="punct">,</span><span class="symbol">:update</span><span class="punct">,</span><span class="symbol">:destroy</span><span class="punct">]</span>
  <span class="ident">helper</span> <span class="symbol">:all</span> <span class="comment"># include all helpers, all the time</span>

  <span class="comment"># See ActionController::RequestForgeryProtection for details</span>
  <span class="comment"># Uncomment the :secret if you're not using the cookie session store</span>
  <span class="ident">protect_from_forgery</span> <span class="comment"># :secret =&gt; 'b845cf981afbfef06600e5d7f23e0fed'</span>
<span class="keyword">end</span></pre></div><p>&nbsp;</p><p><span style="font-size: medium"><strong>步骤九：客户端</strong></span></p><p>&nbsp;</p><p>我们可以通过curl或浏览器测试，但是ActiveResource真正的魅力是使用ruby对象测试。所以我们将创建一个简单的客户端api。在lib目录下建一个文件&quot;ares_sample_client.rb&quot;，并加入以下代码：</p><div class="typocode"><pre><span class="ident">require</span> <span class="punct">'</span><span class="string">activeresource</span><span class="punct">'</span>

<span class="keyword">module </span><span class="module">Sample</span>
  <span class="keyword">module </span><span class="module">Client</span>
    <span class="keyword">class </span><span class="class">API</span>
      <span class="keyword">class </span><span class="class">Post</span> <span class="punct">&lt;</span> <span class="constant">ActiveResource</span><span class="punct">::</span><span class="constant">Base</span>
        <span class="constant">self</span><span class="punct">.</span><span class="ident">site</span> <span class="punct">=</span> <span class="punct">&quot;</span><span class="string">http://localhost:3000</span><span class="punct">&quot;</span>
      <span class="keyword">end</span>
      
      <span class="keyword">class </span><span class="class">Comment</span> <span class="punct">&lt;</span> <span class="constant">ActiveResource</span><span class="punct">::</span><span class="constant">Base</span>
        <span class="constant">self</span><span class="punct">.</span><span class="ident">site</span> <span class="punct">=</span> <span class="punct">&quot;</span><span class="string">http://localhost:3000</span><span class="punct">&quot;</span>
      <span class="keyword">end</span>
    <span class="keyword">end</span>
  <span class="keyword">end</span>
<span class="keyword">end</span></pre></div><p>&nbsp;</p><p>现在我们可以同两国console来测试我们的成果了，确保server启动在3000端口，并且启动console：script/console</p><div class="typocode"><pre>          
&gt;&gt; require 'ares_sample_client.rb'
=&gt; [&quot;Sample&quot;]
&gt;&gt; posts = Sample::Client::API::Post.find(:all)
=&gt; [#&lt;Sample::Client::API::Post:0xb710bec4 @attributes={&quot;updated_at&quot;=&gt;Wed Jan 09 02:36:34 UTC 2008, &quot;id&quot;=&gt;1, &quot;content&quot;=&gt;&quot;The first post&quot;, &quot;user_id&quot;=&gt;1, &quot;created_at&quot;=&gt;Wed Jan 09 02:36:34 UTC 2008}, @prefix_options={}&gt;]
&gt;&gt; 

&gt;&gt; p = Sample::Client::API::Post.create
ActiveResource::UnauthorizedAccess: Failed with 401 Unauthorized
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/connection.rb:125:in `handle_response'
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/connection.rb:112:in `request'
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/connection.rb:101:in `post'
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/base.rb:803:in `create'
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/base.rb:636:in `save_without_validation'
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/validations.rb:262:in `save'
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/base.rb:339:in `create'
        from /usr/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/core_ext/object/misc.rb:28:in `returning'
        from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/base.rb:339:in `create'
        from (irb):3
&gt;&gt; </pre></div><p>&nbsp;</p><p>我们的API成功了，认证系统也发挥作用了。我们没有通过认证，所有不能够创建post，那么现在我们就加入认证来测试一下：</p><div class="typocode"><pre><span class="keyword">module </span><span class="module">Sample</span>
  <span class="keyword">module </span><span class="module">Client</span>
    <span class="keyword">class </span><span class="class">API</span>
      <span class="keyword">class </span><span class="class">Post</span> <span class="punct">&lt;</span> <span class="constant">ActiveResource</span><span class="punct">::</span><span class="constant">Base</span>
        <span class="constant">self</span><span class="punct">.</span><span class="ident">site</span> <span class="punct">=</span> <span class="punct">&quot;</span><span class="string">http://test1:test1@localhost:3000</span><span class="punct">&quot;</span>
      <span class="keyword">end</span>
      
      <span class="keyword">class </span><span class="class">Comment</span> <span class="punct">&lt;</span> <span class="constant">ActiveResource</span><span class="punct">::</span><span class="constant">Base</span>
        <span class="constant">self</span><span class="punct">.</span><span class="ident">site</span> <span class="punct">=</span> <span class="punct">&quot;</span><span class="string">http://test1:test1@localhost:3000</span><span class="punct">&quot;</span>
      <span class="keyword">end</span>
    <span class="keyword">end</span>
  <span class="keyword">end</span>
<span class="keyword">end</span></pre></div><p>&nbsp;</p><p>需要注意的是，认证应用在整个类...这是的api使用相当容易，但是使多个用户使用变困难了，不管如何，我们的程序起作用了，我们再看看：</p><div class="typocode"><pre>&gt;&gt; p = Sample::Client::API::Post.create(:content =&gt; &quot;Should succeed&quot;, :user_id =&gt; 1)
=&gt; #&lt;Sample::Client::API::Post:0xb71b81d8 @attributes={&quot;updated_at&quot;=&gt;Wed Jan 09 02:55:22 UTC 2008, &quot;id&quot;=&gt;3, &quot;content&quot;=&gt;&quot;Should succeed&quot;, &quot;user_id&quot;=&gt;1, &quot;created_at&quot;=&gt;Wed Jan 09 02:55:22 UTC 2008}, @prefix_options={}&gt;
&gt;&gt; p.save
=&gt; true
&gt;&gt; </pre></div><p>&nbsp;</p><p>非常好！</p><p>&nbsp;</p><h2><a href="../../../blog/162276">请继续阅读本教程的第二部分</a></h2>
          <br/>
          <span style="color:red;">
            <a href="http://weskycn.javaeye.com/blog/156675#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 16 Jan 2008 17:02:53 +0800</pubDate>
        <link>http://weskycn.javaeye.com/blog/156675</link>
        <guid>http://weskycn.javaeye.com/blog/156675</guid>
      </item>
      <item>
        <title>多对多关联分页，用will_paginate插件实现</title>
        <author>weskycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://weskycn.javaeye.com">weskycn</a>&nbsp;
          链接：<a href="http://weskycn.javaeye.com/blog/146735" style="color:red;">http://weskycn.javaeye.com/blog/146735</a>&nbsp;
          发表时间: 2007年12月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>在做项目的时候碰到这样一个问题，有两个模型：category和content，他们是多对多的关联，他们的关联模型是categoring</p>
<p>我要做的是根据某个特定的category来检索content，并对content分页。</p>
<p>Controller的代码：</p>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-rb">
    <li class="alt"><span><span class="variable">@category</span><span>&nbsp;=&nbsp;Category.find(params[</span><span class="symbol">:id</span><span>]) &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>content_ids&nbsp;=&nbsp;</span><span class="variable">@category</span><span>.categorings.collect{</span><span class="variable">|categoring</span><span>|&nbsp;categoring.content_id}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="comment">#首先取出中间表里该模型的记录集合（数组） </span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;!(content_ids&nbsp;==&nbsp;[])&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="comment">#然后判断该集合是否为空，如果为空则不做查询分页 </span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="variable">@contents</span><span>&nbsp;=&nbsp;Content.paginate(</span><span class="symbol">:all</span><span>,</span> </li>
    <li class=""><span></span><span class="symbol">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :conditions</span><span>&nbsp;=&gt;&nbsp;</span><span class="string">&quot;id&nbsp;IN&nbsp;(#{content_ids.join(',')})&quot;</span><span>,&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span class="symbol">:page</span><span>&nbsp;=&gt;&nbsp;params[</span><span class="symbol">:page</span><span>],&nbsp;</span><span class="symbol">:per_page</span><span>&nbsp;=&gt;&nbsp;2)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#ff0000">#如果不为空则对关联表进行分页（利用will_paginate插件）</font> &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">end</span><span>&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>&nbsp;然后就可以在views中利用<!--will_paginate @contents-->进行分页了。</p>
          <br/>
          <span style="color:red;">
            <a href="http://weskycn.javaeye.com/blog/146735#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 07 Dec 2007 16:45:44 +0800</pubDate>
        <link>http://weskycn.javaeye.com/blog/146735</link>
        <guid>http://weskycn.javaeye.com/blog/146735</guid>
      </item>
      <item>
        <title>Cache_fu插件使用方法（翻译：持续补充更新）</title>
        <author>weskycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://weskycn.javaeye.com">weskycn</a>&nbsp;
          链接：<a href="http://weskycn.javaeye.com/blog/133797" style="color:red;">http://weskycn.javaeye.com/blog/133797</a>&nbsp;
          发表时间: 2007年10月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <h2><font size="1"></font>&nbsp;</h2>
<p>Chris 曾经在Gamespot工作，他在这里谈论游戏。在过去的一年党中，有无数的年轻人在不停地刷新这个网站，而此网站依然坚挺。他们每天要处理50M地页面，没有down掉。他们用Memcache做到了这点。</p>
<p>Memcache 是个分布式的hash，由Livejournal开发。</p>
<p>你会选择用Memcache吗? </p>
<p><strong>Rails and Memcache</strong></p>
<p>用Fragments, Actions, Sessions, Objects缓存， 你可以使用:</p>
<ul>
    <li><code>memcache-client</code> (by Robot-coop guys/Eric Hodel). Marshal.unload is 40 times faster than Object.new/loading from the database. </li>
    <li>CachedModel &ndash; integration with ActiveRecord </li>
    <li>Fragment Cache Store </li>
    <li>Memcache session store </li>
</ul>
<p>&hellip;或者&hellip;</p>
<h2><code>cache_fu插件</code></h2>
<p>或者叫&nbsp;<code>acts_as_cached 2.0。它覆盖以上讨论的所有Objects，只需要配置一个YAML 文件（config/memcached.yml）.提醒：不要在服务器配置文件中使用names.而是要用IPs,为了避免BIND和每次连接都连接数据库.</code></p>
<ul>
    <li><code>get_cache</code> </li>
    <li><code>expire_cache</code> </li>
</ul>
<p>你需要的只有这些--你过你用set_cache,你可能不清楚改插件是如何工作的。要在在after save钩子上使用缓存失效机制。例如：</p>
<div class="typocode">
<pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">Presentation</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
  <span class="ident">acts_as_cached</span>
  <span class="ident">after_save</span> <span class="symbol">:expire_cache</span>
<span class="keyword">end</span></code></pre>
</div>
<p>再如：</p>
<p><code class="typocode_ruby "><span class="keyword">class </span><span class="class">Presentation</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span><br />
&nbsp; <span class="ident">acts_as_cached</span> <span class="symbol">:conditions</span> <span class="punct">=&gt;</span> <span class="punct">'</span><span class="string">published = 1</span><span class="punct">'</span><br />
<span class="keyword">end</span></code></p>
<p>Cached-scoped-finders (译者注：不知如何翻译).。这个用法将会把自定义地find方法挪到model上，然后在其中包装一些缓存机制，cache_fu插件通过AR::Base方法将这个功能有机结合起来。</p>
<div class="typocode">
<pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">Topic</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
  <span class="keyword">def </span><span class="method">self.weekly_popular</span>
    <span class="constant">Topic</span><span class="punct">.</span><span class="ident">find</span> <span class="symbol">:all</span><span class="punct">,</span> <span class="punct">...</span>
  <span class="keyword">end</span>
<span class="keyword">end</span>

<span class="constant">Topic</span><span class="punct">.</span><span class="ident">cached</span><span class="punct">(</span><span class="symbol">:weekly_popular</span><span class="punct">)</span></code></pre>
</div>
<p>用<code>alias_method_chain方法将date加入到缓存键：</code></p>
<div class="typocode">
<pre><code class="typocode_ruby "><span class="keyword">def </span><span class="method">self.cache_key_with_date</span><span class="punct">(</span><span class="ident">id</span><span class="punct">)</span>
  <span class="punct">...</span>
<span class="keyword">end</span>

<span class="keyword">class </span><span class="punct">&lt;&lt;</span> <span class="constant">self</span>
  <span class="ident">alias_method_chain</span> <span class="symbol">:cache_key</span><span class="punct">,</span> <span class="symbol">:date</span>
<span class="keyword">end</span></code></pre>
</div>
<p>用ID加载缓存：由<code>Topic.find(1, 2, 3)转变为<code>Topic.get_cache(1, 2, 3)，这样可以将缓存数据放入memcached，并且在以后访问他们。</code></code></p>
<div class="typocode">
<pre><code class="typocode_ruby "><span class="ident">user_ids</span> <span class="punct">=</span> <span class="attribute">@topic</span><span class="punct">.</span><span class="ident">posts</span><span class="punct">.</span><span class="ident">map</span><span class="punct">(&amp;</span><span class="symbol">:user_id</span><span class="punct">).</span><span class="ident">uniq</span>
<span class="attribute">@users</span> <span class="punct">=</span> <span class="constant">User</span><span class="punct">.</span><span class="ident">get_cache</span><span class="punct">(</span><span class="ident">user_ids</span><span class="punct">)</span></code></pre>
</div>
<p>你也可以缓存关联，因此，你可以通过memcache来导航关联。</p>
<p>缓存重写</p>
<div class="typocode">
<pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">ApplicationController</span> <span class="punct">&lt;</span> <span class="constant">ActionController</span><span class="punct">::</span><span class="constant">Base</span>
  <span class="ident">before_filter</span> <span class="symbol">:set_cache_override</span>
  <span class="keyword">def </span><span class="method">set_cache_override</span>
    <span class="constant">ActsAsCached</span><span class="punct">.</span><span class="ident">skip_cache_gets</span> <span class="punct">=</span> <span class="punct">!!</span><span class="ident">params</span><span class="punct">[</span><span class="symbol">:skip_cache</span><span class="punct">]</span>
  <span class="keyword">end</span>
<span class="keyword">end</span></code></pre>
</div>
<p>reset_cache：重置缓存（这段不知道改怎么翻译了：<code>reset_cache</code>: Slow, uncached operations can sometimes queue up and wedge a site. Instead, issue cache resets on completion of a request, rather than expiring beforehand. That way, requests that continue to pile up will still use the cached copy until the rebuild is complete.）</p>
<div class="typocode">
<pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">Presentation</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
  <span class="ident">after_save</span> <span class="symbol">:reset_cache</span>
<span class="keyword">end</span></code></pre>
</div>
<p>版本：当修改代码后地缓存方式</p>
<div class="typocode">
<pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">Presentation</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
  <span class="ident">acts_as_cached</span> <span class="symbol">:version</span> <span class="punct">=&gt;</span> <span class="number">1</span>
<span class="keyword">end</span></code></pre>
</div>
<p>部署：Chris推键是一能够Monit部署以保证Memcache服务器高效率工作。（译者注：不知其他服务器效率如何）</p>
<p>livketama：在不使缓存实效地情况下重新部署Memcache服务器。</p>
<p>问题: Page caching? Nginx 会使用本地Memcache page caching，即在rails 主机之外。</p>
<p>后记：由于本人最近正在研究cache_fu插件地使用方法，本篇文章会持续更新，敬请关注。欢迎发表您对该插件的理解。</p>
          <br/>
          <span style="color:red;">
            <a href="http://weskycn.javaeye.com/blog/133797#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 20 Oct 2007 12:55:56 +0800</pubDate>
        <link>http://weskycn.javaeye.com/blog/133797</link>
        <guid>http://weskycn.javaeye.com/blog/133797</guid>
      </item>
      <item>
        <title>[转贴]关于豆瓣网的调查分析</title>
        <author>weskycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://weskycn.javaeye.com">weskycn</a>&nbsp;
          链接：<a href="http://weskycn.javaeye.com/blog/127214" style="color:red;">http://weskycn.javaeye.com/blog/127214</a>&nbsp;
          发表时间: 2007年09月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一、 什么是豆瓣？ <br />豆瓣网由前某物流咨询公司CTO杨勃于2005年3月创办，启动资金是杨勃几个朋友共计不到20万人民币的天使投资，以独到的书评、影评、乐评主题社区著称，因为开创了国内Web2.0新模式而闻名。从构想到技术实现均由杨勃一人完成，业内对此有“一个人的豆瓣”的评价。豆瓣的得名来自于杨勃曾经居住的北京朝阳门附近的豆瓣胡同。 <br /><br />（一）alexa数据 <br />1.alexa排名：1699（3月平均） <br /><br />表一：6个月排名数据变化表 <br /><br />2. 每百万用户登陆数：391（3月平均） <br /><br />表二：6个月访问人数变化表 <br /><br />3. 单个用户页面浏览量：9.1（3月平均） <br /><br />（二）网站相关数据 <br />官方页面数据： <br />1. 成立于2005年3月6日 <br />2. 注册成员数：145044 <br />3. 城市居民数：22258（注册成员中按城市自主分类者） <br />4. 成立小组数：5981 <br />备注：以上具体数据均为2006/4/18页面即时数据。 <br /><br />页面观察数据： <br />1． 平均每天增加注册成员900人左右 <br />2． 平均每天增加城市居民数150人左右 <br />3． 平均每天增加小组数50个左右 <br />4． 小组数据：超过1500个小组是10人以上，最多人数小组为“爱看电影”（5537人）；60%的小组为5人（含5人）小组，其中1人小组占40%。 <br />备注：以上观察数据均为2006/4/7—2006/4/18时间段内页面观察所得。 <br />从以上数据，豆瓣的用户发展数目比起同级别排名的网站并不算突出；从数据图表可见，它的用户曲线和访问曲线都是比较平缓的，考虑到它的网站性质和经营策略，豆瓣的用户基数和用户上升幅度虽然不高，但目标用户比例较高，用户的流失相对减少。 <br /><br />（三）网站发展状况 <br />●2004年9月杨勃为自己的旅行网站制作了商业计划书，并且将这个网站命名为“驴宗”，在论证这个商业计划时朋友的建议让杨勃放弃了“驴宗”，将眼光投到“书”这个更宽广的领域。 <br />●从2004年10月开始开发，经历了5个月，2005年3月6日，杨勃的豆瓣网开张了，并且第一天就有用户注册。 <br />★05/04/09 小组藏书功课开通。 <br />★05/04/12增加小组发言修改功能；增加针对某本书的评论，分离了对某本书的评论和讨论；对关键词的搜索结果确定以站内收藏人数排序。 <br />★05/04/14豆瓣的界面特别是收藏部分做了大的更新，对URL也有简化。 <br />★05/04/19增加 “和你口味最像的人”，还在部分书的介绍页里开通了“豆瓣成员认为类似的书”。 <br />★05/04/20针对用户和小组推出个性化域名服务。 <br />★05/04/22推出针对站内评论的rss feed。 <br />★05/04/25第一个公益性质的小组出现在豆瓣。 <br />★05/04/27用户上传书目功能开通（试验性运行）。 <br />★2005年5月2日，因为小组“爱看电影”的迅猛发展，豆瓣电影单列开通。 <br />★05/05/23开通“WISHLIST”，开始测试对个人的推测清单。 <br />★05/06/06 “标签”从豆瓣的主菜单里消失了，标签列表成为豆瓣读书和豆瓣电影页面的一部分。 <br />★05/06/14增加了代码生成器，用户看过、在看、想看的书或者电影都可以自动显示在自己的BLOG上。 <br />★2005年7月6日，因应香港用户快速增长及活跃，开通繁体字版本，网站针对港台用户增加个性化服务；相关的更新，豆瓣增加数万种港台出版的图书名目，还有在台湾第二、三大网上书店——金石堂和诚品的购买链接和售价；增加了旌旗书市的购买链接和价格。 <br />★2005年7月18日，豆瓣音乐单列开通。 <br />●到2005年7月底，豆瓣网注册用户已接近万名，日访问量近20万。 <br />★2005年8月23日，豆瓣推出同城。 <br />●到2005年9月底，豆瓣网注册用户已达3万多名，日访问量超过20万。 <br />★2005年10月7日，开通二手书碟交换功能。 <br />●2005年11月，网站从上海搬到北京运营。 <br />●2005年12月，豆瓣网英文版（http://www.douban.net/）上线，��...��的合作。 <br />●到2005年12月，由1个人开发、4个人运营的书评、影评、乐评网站豆瓣网，已经有5万多名注册用户。 <br />●到2006年2月，豆瓣网注册用户过10万。 <br />●到2006年3月，豆瓣网开通一周年，注册用户过11万。4000+个小组，50人以下小组占90%。 <br />备注：带●标志信息为网站市场规模发展情况，循相关新闻报道整理；带★标志信息为网站功能服务发展情况，循网站站务网志整理。 <br /><br />（四）网站市场推广手法及品牌现状 <br />与传统门户网站依靠大规模、高成本的市场营销推广自己的手法相异，“豆瓣”的知名度基本上是通过最原始的人际传播方式实现的，也就是依赖于“一传十、十传百”的口碑传播。 <br />要让用户产生指数型上升，不光要东西好，还要有两种人：一种是识货的人，他们扮演着意见领袖，周围的人对他们高度信任；还有一种是天生的传播者，他们虽然可能只略知一二，却玩命地对跟人谈论新鲜事物，成为人际网络的枢纽。在豆瓣网的用户群里，两种人都不缺。 <br />在网站创始人杨勃看来，豆瓣网的成长历程中有三个关键的时间点。第一个，是网友topku在自己的BLOG上提到了豆瓣网，那代表着用口碑传播开始自发进行；第二个，是IT评论人洪波在BLOG上提到了豆瓣网，从那以后，豆瓣网开始成为网上的主流话题之一；第三个，是他听用户说，有朋友在日常谈话里提到了“豆瓣”，口碑传播终于蔓延到线下。 <br />而事实上，虽然豆瓣以其产品的吸引力确实引来IT界的广泛关注和用户群的自发传播，但在其运营上还是有市场促进动作的： <br />首先，网站建站伊始就在《读书》和《万象》这两本国内相对高端的读书类杂志投放过广告，此后也保持着一定的投放频率，这是在目标用户群明确基础上的针对性市场导入行为。 <br />其次，网站在功能设置上很注意与用户个人站外BLOG的关联导引，鼓励并教导用户把豆瓣的图、文通过URL的形式作为个性内容补充到个人的站外BLOG中，这是一种与市场领先产品主动结合的开放性市场推广思维。 <br />再次，豆瓣在运营中注意掌握类别用户，如在《查令十字街84号》在国内上市前后，该书的中文版译者在豆瓣网上和读者们频繁互动，还把自己其他译作的读后感拿出来和网友们分享。而在此之后，有很多中文译者慕名加入了豆瓣的用户群，由此而来是更广范围的用户辐射作用。而在香港用户表现活跃之际，豆瓣网就顺势推出了针对港台用户的系列个性化服务，令该地区用户此后增长明显。 <br />现在，豆瓣网被视为中国WEB2.0应用的示范网站，在多个行业评选和第三方排名中皆处于前列。除了每月增长的用户数字，能证明其成功和品牌效应的莫过于遍地开发的仿“豆瓣”网站，就连成名已久的大众点评网，在其最新上线的3.0版本从产品、架构到引导文字都有很明显的豆瓣痕迹。 <br />当然，豆瓣网能够在一年的时间内达到现在的市场规模，在业内引起这么广泛的回响和研究热潮，收获那么多的用户口碑，归根到底还是在它能抓准用户定位、把握到用户核心需求并能提供到相关服务这一关键市场点上。 <br /><br />二、 豆瓣钱途 <br />网站的前期投资仅仅是来自杨勃几个朋友的20万人民币。豆瓣的团队现在是5个人，杨勃把自己定位于“技术人员”，在剩下的2名全职员工中，一位负责技术，一位负责公关和市场推广。另外还有2名兼职员工，杨勃未曾谋面，他们都是豆瓣网的注册用户，因为喜爱网站，自发地希望为豆瓣做点事，分别身处南昌和武汉，帮忙处理一些社区和网站内容方面的工作。豆瓣网的主要支出是域名费用、服务器托管费用和人员费用。 <br />目前，豆瓣的收入虽然不大，但已经足够支撑网站的日常运转。在同类网站中，豆瓣是少数自给自足的个例之一。现在豆瓣的收入来源主要有两点： <br />1、 与网上零售商进行分成：豆瓣页面目前已经有十几家网站的“比价”，每次有用户通过豆瓣网上的链接进入当当、卓越这样的大型网上商城购物，双方就会按照事先约定的比例进行利润分成。这是目前豆瓣网最重要的收入来源。 <br />2、 网络广告：目前并不多，看得出，这是网站为了保持本身风格做的刻意安排。 <br />豆瓣宣称它要做永远的BETA版，这不仅表现在它不断的产品更新上，也可以体现在对它日后盈利模式的预测分析上。现在的豆瓣，被认为处于产业链的中间位置，重点服务人消费物（书、电影、唱片）“之前”的阶段，提供用户直达“之后”的渠道，欠缺“之中”的过程。发展中的豆瓣，一点变数就可能导引到不同的方向，因此对它的盈利模式不妨以整体产业链架构引发不同的猜想： <br />上游——成为用户权威参考，服务其他生产商，自身也可以是生产商。 <br />1、 行业标准：通过高质评论和喜好人群的大量汇聚树立品牌，成为中国版的《伦敦书评》、蓝屋书榜、《米其林指南》，主导并出版相应的榜单、指引、评选。 <br />2、 营销合作：与生产商合作推广，甚至策划推出直接满足某类群体需求的产品。 <br />如有很多不是为了畅销而出版的图书，用门户网站铺天盖地的推广方式不但成本高，而且很难达到满意的效果。但与站内人与人自发口碑传播、信任度高的豆瓣合作则很有事半功倍的效果。在北京文化圈中备受推崇的《读库》文丛就已经尝试过与豆瓣网进行这方面的营销合作。 <br />当豆瓣用户达到一定基数的规模后，豆瓣对产品的销售就可以产生决定性的影响力。而且由于豆瓣对人群意见的即时征集和反馈能力，这个影响不仅可到达产品生产后的销售，还可以延伸作用到产品诞生之前的策划，直接促进产品的产生。 <br />3、 网络广告：分众人群的广告投放。 <br /><br />中游——用户在线消费服务提供商 <br />1、 内容收费：无论是书、电影、音乐，现在网络上最大的需求都是在线视听和下载。现时的豆瓣开宗明义宣布：为避免版权纠纷，豆瓣不会提供类似的服务。那当版权问题解决，用户消费环境形成后呢？一个汇聚产品消费者的网络社区提供产品给消费者即时消费不是顺理成章的事吗？ <br />2、 增值服务收费：写/看评论（BLOG）、查询最新上市的产品/榜单/指引、获取产品/线下合作方优惠资讯，这些都可以做无线应用。 <br /><br />下游——电子商务网站 <br />1、直销平台：是对现在渠道作用的延伸。在有资源配合的前提下，豆瓣甚至可以类似携程开设如家那样，开设自己的线下渠道，承担起整条产业链从策划、生产、销售到配送的全过程。 <br />2、二手交易收费平台：现在站内的二手交换是因应用户需求的一个功能，当豆瓣有资源投入，有完善的用户信用、支付系统和相互认证保障后，升级服务后对用户收费也是一个途径。 <br />豆瓣一直给人“小众”的感觉，在杨勃的理念中，这可以用“长尾”理论解释前景，强调对利基市场的重视，认为无数小生意的价值总和足以超过个别大市场。但对于很多为VC抄豆瓣的从业人员，它的快速规模化一直是思考的问题。但另一方面，豆瓣之所以能成为豆瓣，与它这种“小众”的品位和氛围又密不可分。商业化介入、规模化后的豆瓣还是那个“豆粉”们喜爱信任的豆瓣吗？“小众”不再的豆瓣还能依旧保持它引以为荣的人文精神吗？横向发展多条产业链的豆瓣能成功整合多头并进吗？这些问题的解答将直接决定以上猜想模式的最终走向。 <br /><br />三、 豆瓣产品 <br />网站思路 <br />豆瓣表面上看去是一个评论（书评、影评、乐评）网站，但实际上它却提供了书目推荐和以共同兴趣交友等多种服务功能，它更像一个集BLOG、交友、小组、收藏于一体的新型社区网络。 <br />在杨勃的眼中，“人”才是最重要的。如果说门户类网站还是以“物”为第一要素，一些社会类网站则把“人”提到了第一要素，那么，豆瓣，则是第一个把“人”和“物”放在同等重要地位的网站。 <br />随着豆瓣英文版的推出，豆瓣有望成为中国第一家向外输出模式的网站，而实际上，豆瓣自身就是集众家所长的结果。至于豆瓣究竟借鉴了哪些网站哪些元素呢？据杨勃介绍一共有三个方面。一是简约素雅的界面风格，来自于flickr，包括它的分享概念；二是电子商务方面，借鉴了亚马逊（Amazon），比如用户评论和推荐；三是社会网络（SNS）的一些元素，把人和人的社会关系真实地搬到网上，不过一般的社会网络是没有媒介的，而豆瓣用相同兴趣作为媒介。 <br />杨勃将豆瓣的核心思想总结为，“可以发现不同的东西，并且适合自己”，他解释说，朋友的推荐往往对购买某种产品非常关键，现在豆瓣扩大了推荐的群体，你会相信特定陌生人的推荐，这“可以理解为一种以书等具体物体为媒介的人脉关系网”。 <br /><br />产品体验 <br />豆瓣是100%的动态网站。呈现给每个注册用户的主页都是各不相同的，而同一个用户在不同时间上豆瓣，也会看到不同的首页。动态、个性，这都是豆瓣带给用户的web2.0体验。 <br />以目前的豆瓣首页举例，在用户登陆之前，左上方是搜索功能，可以搜索一切豆瓣已有记录的书、电影和唱片，右上方是豆瓣网的使用引导，这两项是固定不变的。左下方是“近期好评”，是站内评论的提取，显示5条，提取内容包括评论人图像、ID、被评论产品名、评论题目、部分评论内容、评论等级及回应数，根据用户投票是否“有用”而动态调整。右下方是“过去几分钟里，豆瓣知道”，显示12项最新站内用户对产品的标识，是即时变动的。 <br />在用户登陆之后，首页左边的架构不变，右上方被替换成“号外”，通知关于豆瓣的一切新闻。而在“号外”和“过去几分钟里，豆瓣知道”之间新插入了 “豆瓣猜你会喜欢”，也就是豆瓣根据你过去在网站内的收藏和评价等等行为，对你的爱好作估计，向你推荐好书好碟，调整完全因人而异。 <br /><br />网站架构 <br />记录分享、发现推荐、会友交流，这是豆瓣在用户网站使用指南中的对用户站内路径的指引，分别也可对应豆瓣导航的三大组成块：品味系统（读书、电影、音乐）、表达系统（我读、我看、我听）和交流系统（同城、小组、友邻）。 <br />品味系统——读书、电影、音乐 <br />三个首页页面架构相似：用户登陆前后一致，左上方是搜索功能，可以搜索一切豆瓣已有记录的相应类别的产品，这项是固定不变的。左下方是“豆瓣成员的近期好评”，是站内该类别最新产品评论的提取，显示5条，提取内容包括评论人图像、ID、被评论产品名、评论题目、部分评论内容、评论等级及回应数，根据用户投票是否“有用”而动态调整。 <br />右上方是豆瓣用户对该类别产品的标签汇总，提取了最多人数的36个。右下方三个类别各有不同，读书是“豆瓣在读最多的书 (top9)”，电影是“豆瓣电影排行 (top9)”，音乐是“最新增加的音乐/提供者”和“豆瓣最热音乐 (top9)”。上述所有项都是动态调整的。 <br />在单个产品页面，对于游客，网站提供产品资料（销售及内容信息）和其他用户对产品评论这些资讯类信息，同时提供搜索、比价、二手交换、链接购买这几项服务。网站通过“常用的标签”、“喜欢XX的人也喜欢”、“豆列推荐”形式对用户进行推荐，引导用户站内流动。通过站内其他用户使用该产品状态显示和收藏该产品小组列表引导用户进行单对单、单对群的交友行为。 <br />在用户登陆后，除了上述内容，用户可参与修改产品信息，类似WIKI的应用。用户不但可以看别人的意见，还可以对意见评价“有用”与否和跟帖，也可以进入该产品的论坛发帖或参与讨论，类似百度贴吧的应用。用户可以对产品标识自己“过、在、想”的状态把产品列入自己的收藏夹，可以对此标识不多于5个标签整理自己的收藏夹，也可以在五个评价级别中选择一个直接表述自己的态度。以上用户行为被网站记录，不但在“我的豆瓣”中体现，还进入到网站的数据库，透过豆瓣设定的计算模型，对网站的页面数据提取直接影响。 <br />该部分架构是资讯（相关产品）+功能服务+推荐（人和物），核心是资讯内容，关注点在“物”。在这里，豆瓣是一个文化产品资料库，不同于图书馆电子版一对多的开放分享，豆瓣由于开放给所有用户参与建设，因此是一个动态变化趋向完整的文化产品资料库，形成的是多对多的分享交流。正因为有交流元素的介入，所以豆瓣强调了参与建设信息的有用与否（评价和讨论），令贡献信息的私人性（BLOG元素）变得公众化（BBS和贴吧）。 <br />而与论坛交流的公众性相比，由于豆瓣加入了计算模型这个技术核心应用，用户完善这个资料库的同时，它也把最符合用户爱好的产品推荐到用户面前，保证了用户使用上的个性化。 <br />由于品味系统页面在用户登陆前后是一致的，页面推荐更多体现的是站内用户的集中意见，在某些功能产品上，例如站内广泛分布的排行榜，就很容易出现“公众暴力”的现象，导致很长时间内都没有更新，这对用户来说并不是一个很好的体验。 <br /><br />表达系统——我读、我看、我听 <br />属于用户管理系统，登陆前跳转到注册页面，登陆后进入用户管理站内信息页面。 <br />我的豆瓣：页面左边是用户站内发布信息汇总，发表评论、回应评论、讨论话题从上而下分列。右边是功能服务管理区，包括产品搜索、个人主页链接、收藏夹链接（读、看、听）、交友链接（友邻和小组）、创建豆列（系列性推荐）、二手交换发布。 <br />我读、我看、我听：实质就是用户分别就读书、电影、音乐的收藏夹。三个页面架构一致，左边是产品状态区，从上到下分别是“在、想、过”，其中电影只有“想和过”两种状态设置，信息来自于用户之前在单一产品页面的标识动作。除了状态，用户可以标签的形式对收藏夹的产品做分类整理。页面右边是网站服务区，上边是产品搜索功能，下边是豆瓣根据用户过往站内行为（评价及收藏）对用户作出的相应产品推荐，一次6个，动态调整。 <br />个人主页：左边是用户对站内“物”的行为记录，包括收藏、评论。右边是交友信息，有用户个人信息（所在城市、外部BLOG地址、自我介绍等），沟通功能键（加为友邻、发豆邮）、用户状态栏（是否为友邻），此外还有用户对站内“人”的行为记录，包括小组和友邻。 <br />表达系统是品味系统与交流系统的联接。如果说品味系统关注“物”，交流系统关注“人”，那表达系统就是通过用户个体融合这两个重点。 <br />以“我的豆瓣”中的内容为例，用户站内发布信息汇总（评论、回帖、讨论），收藏行为、向外推荐和交换信息都是用户对品味系统的贡献。而这些内容共同组成用户的个人展现，达成其参与交流系统。而豆瓣在这里向用户作出的产品推荐更像是书友会的目录，是以用户个体行为和用户交流系统中触及到的其他用户行为向用户作出推荐，更有针对性，也可以看作是交流系统对表达系统的反馈。 <br />在个人展现部分，收藏（列表）是豆瓣的核心体现，好比个人的网上书架。在豆瓣，个人展现应用方面的“收藏”还不单指“物”，还包括“人”，因网站交友功能上的薄弱，“友邻”的作用更多地表现在“友邻”对“物”的收藏上，所以用户对外展现的是自己和友邻的收藏，通过物和物、人和物的关系表达。 <br /><br />交流系统——同城、小组、友邻 <br />同城：页面左边从上到下分别列了全站读书、电影、音乐各十大排行，排行根据站内用户对产品评分动态调整。右上方是“直达链接”，提取成员主要分布的十个国内城市名和已有居民数，点击去到相应城市页面。右下方是“国家和地区”，是站内所有用户所在国家和地区提取，点击去到相应地区页面。 <br />十个“直达链接”的城市页面架构一样，左上方是“我住在XXX”，用户点击后豆瓣就记录其为该城市居民，以后用户进入“同城”就直接进入该城市页面，想撤消状态就在该页面再按一次“搬家”。“我住在XXX”以下依次是“二手交换”和该城市读书、电影、音乐各十大排行。“二手交换”是豆瓣该城市居民发布的交换信息最新列表，排行则是根据该城市居民对产品评分动态调整，因此这个排行在各个城市/地区都有差异。右上方是“XXX新成员”，列出4个新加入该城市的居民，显示图像和名字，即时更新。下面依次是“XXX的成员喜欢去的小组”，列12个，显示图像、名称、人数，按人数降序排序，提取是从所有小组里随机，每15分钟更新一次。最下方是“最近发生”，，显示12项最新该城市用户对产品的标识，是即时变动的。 <br />用户加入某城市后，登陆后点击“同城”会直接进入相应城市页面。 <br />小组：用户登陆前，首页左上方是“最受欢迎的小组”，显示15个人数最多的小组，按人数降序排列，提取内容是图像、名称、人数，按实际动态调整。左下方是“所有小组的最新话题”，是对站内所有小组新发话题的提取，显示的是话题标题、小组名、发帖人名、回应数和最后回应时间，即时更新。 <br />页面右上方是搜索功能，可以搜索站内所有小组，该项是固定的。往下依次是“新成立”，显示10个最新成立的小组，提取名字和人数，即时更新。最下面是“合作媒体”，提供合作方《书屋》、《书城》、《天涯》这三本读书类杂志在豆瓣的官方读者小组快速入口，该项固定。  <br />用户登陆后，左上方是 “我参加的小组”，是用户所有参加小组的列表，显示图像、名称、人数。下面接着的是“我所在小组的最近话题”，是对用户所有参加小组新发话题的提取，最下面是“所有小组的最新话题”，与登陆前一致。 <br />右边页面在用户登陆后在原来页面基础上增加了两个板块，搜索下增加了“创建一个新的小组”功能，用户只有加入一个小组后才有创建小组的权利，创建过程很简单，只需填写小组名称、介绍、标签（不超过5个）。再下面也是新增的“15分钟名组” ，是小组按豆瓣算法的随机提取，显示图像、名称、人数，按人数降序排序，每15分钟更新一次。 <br />单个小组页面功能有论坛、成员列表、小组收藏、成员常去的其他小组列表，成员主要的交流方式是论坛讨论。 <br />我的友邻：登陆前进入注册页面，登陆后进入用户交友管理页面。 <br />该页面提供用户站内搜索和邀请（站外邮件邀请）功能，用户站内交友状态栏（已加和被加友邻）。网站推荐“人”的信息，包括即时性的网站新成员显示和豆瓣通过用户已有行为计算出的兴趣相仿用户——“豆瓣认为和你口味最像的”。这些用户列在豆瓣“我的友邻”页面右下角，用户可以详细浏览他们看过的书和电影，决定是否将其列为自己的友邻。一旦这些成员成为友邻，用户可以很方便了解到他们的动态信息：比如他们正在看的书、想看的书，添加的书评等。用户间的联系方式主要是通过“豆邮”，类似碰碰“小纸条”的站内信息交互方式。 <br />“同城”、“小组”、“友邻”，从交友来说，这是一个范围逐渐缩小的过程。豆瓣在这之上加入了共同爱好“物”这个媒介，交友纬度增加了，使得豆瓣相对于一般交友网站或者QQ更有针对性。 <br />基于SNS建立的网站大多是交友类型的，但豆瓣中的交友功能只能算附属品。首先网站在交友服务上比较薄弱，小组（群交友）只有论坛，友邻（单对单）只有豆邮，用户交互方式需要拓展；其次网站“物”的体现压倒了“人”，用户个体的关注点在“物”，“友邻”的作用更多地体现在帮助用户找到“物”上。  <br />总括来说，豆瓣目前提供的服务有：特定用途的检索（书、电影、音乐，还有本站内的用户）、购买渠道推荐（“在哪里买”）、特定商品的比价（“一网打尽10多家网店”）、资料的存储和共享（“我的豆瓣”和“别人眼里我的主页”）、站内线上交互（“小组讨论”和“豆邮”）、SN（“友邻”和“同城”）、“二手交换”，还有“豆瓣推荐”（“猜你会喜欢”和“豆瓣认为和你口味最像”）。 <br /><br />产品原则 <br />在用户引导上，豆瓣强调用户参与原则，用户参与的越多，收获也就越多。如用户只有加入一个小组后才有创建小组的权利，需要用户有9个以上的收藏并且给出了评价之后，豆瓣才会向其推荐成员，让其拥有二手交换发布和推荐豆列的权利。这是豆瓣基于计算模型需要作出的约定，但同时却令用户有不断发现的惊喜。 <br />在用户路线上，豆瓣采分散集中的原则，产品线上的是分散，功能键都设置到相应的产品页面上，是过程的体现；用户管理是集中，集中用户在站内的行为，是结果的体现。这种类似购物网站的设置给用户的体验就是方便，而且路线清晰。 <br />在产品设置上，豆瓣采核心需要原则，豆瓣为保证站内用户使用网站的专注，没有贴图，也没有通常社区网站为增加访问量而设的积分和升级系统。这种做法一方面保证了网站垂直运作的专业性，对网站氛围营造起到推波助澜的作用，但另一方面也巩固了网站的“小众”，局限了用户基数的扩展。用户不仅增长缓慢，而且缺少对老用户的激励，一旦市场上出现同类型资源雄厚网站，而网站本身用户积累未达规模，豆瓣的抗击力就很令人担忧。 <br /><br />四、 豆瓣设计 <br />中国用户第一次看douban.com，都有一种登录外国网站的感觉。而事实上，豆瓣简约素雅的界面风格，灵感确实来自于著名的图片网站flickr，学习的还包括它的分享概念。使用这种设计风格，与豆瓣网的产品思维相关，也与豆瓣建站宗旨服务读书人群，与该人群审美喜好吻合。douban.com的网站设计具体做法如下： <br />1、页面技术：采用div+css的页面技术，从《网站重构》一书翻译以来，此种布局方式已经开始深入人心，可说web2.0必备。 <br />2、整体用色：通过色块底色来突出整块内容，重要颜色有浅粉、浅蓝，和白色底结合起来，非常清爽。 <br />3、图片大小：douban.com的核心是书籍、音乐、电影和用户（小组），都采用缩略图，用户（小组）的缩略图小一些。前三者网上的图片一般都比较好看，也必须要大一些，后者因为可以上传，由网站压缩成统一尺寸，所以设计成更小的图，能使得图片显得好看。 <br />4、图片数量：豆瓣网对图片的使用极其吝啬，几乎没有，连用户发评论、发帖都不可发图片。 <br />这样好处是非常明显的，一方面能够使用户专注在文字上，而图片部分都和网站核心相关，不会产生无关的东西。这样的限制与网站用户群锁定喜好阅读人群，较容易接受以文字为主的页面呈现方式相关，对网站独特的用户氛围建立也有帮助。另一方面，这种做法使网站访问速度非常快。 <br />5、网站布局：不管什么页面都是采用相同布局。布局采用上中下方式：最上面为导航；中间为2列方式，左边为页面核心内容，右面为辅助、相关功能及信息；下面是站务导航。所有导航同样没有一张图片。 <br />6、样式用色：样式表使用上豆瓣网也匠心独运，链接选的都是深蓝反白，点上是橙色，删除是深红反白，书籍/音乐/电影使用深红反白，功能说明和站点书签 icon是绿色，推荐的星星是红色，剩下的就是永恒不变的黑色了。整个颜色围绕蓝色和红色色系以及绿色展开，这个和豆瓣网的logo相符，非常协调。 <br />7、按钮设置：button使用得很少。 <br />8、页面长度：每个页面非常短，一般两屏，不超过三屏。 <br />太长的页面会使用户失去耐心，事实上， 3屏以下的页面，用户注意力到达率偏低。因此网站页面长度，2-3屏是最好的选择。长页面只不过是门户网站想多几个广告位置或片面求大求全的做法，并不是每个网站都需要这样。 <br />9、广告设置：豆瓣不同于其他网站，不提供花哨的广告位，目前只有google文字广告和“读书”、“读者”的文字广告在站内一两个页面零星出现。 <br />估计这种克制投放的文字链接广告会是豆瓣网的长期做法，如果提供了传统的图片、flash广告，并在站内广泛分布，势必破坏整个网站苦心经营的人文氛围，整个站点都会变样。 <br />10、用户路径：只做页面跳转，不使用弹出窗口。 <br />这是用户争议比较大的一个应用。豆瓣在这点的应用与西方网站习惯相同，但对习惯中国网站新开窗口方式的大多数中国用户来说，使用豆瓣都有个重新适应的过程。有用户会投诉，想回看之前看到的有兴趣的东西就必须使用浏览器上的“倒退”，相当不方便；又或者只能不断地用鼠标右键新开窗口，对网络新人来说用户体验相当不友好。 <br />在这点的用户体验上，涉及到一个关键的前提，网站需要什么用户的体验。如果网站的目标用户群是接受这种方式，并不会因为这种方式而放弃网站的话，那网站就不需要做出改变，这也可以说是豆瓣“小众”的一个体现。 <br />页面使用跳转的形式与网站受众群相关，大部分都是读书、音乐、电影爱好者，所以让用户尽量顺着同一线路走完，因为这些作品一般人的习惯都是顺着看下去的，中间需要慢慢欣赏体会的时间，没多少人是跳着去欣赏的，也可以认为网站也不鼓励这种蜻蜓点水式的用户行为。这也与网站的用户导引相关，希望用户是每一步都发现新的东西，找到新的兴趣点继续在站内纵横“行走”。另一方面，因为网站在页面设计上做了很多限制，保证了页面跳转速度的快速，所以用户不会因这种方式而影响到对网站的正常使用。 <br />所以那些不习惯不弹出窗口的，可能也不太容易真正在豆瓣网上长久安家，注定也不是它的核心用户。豆瓣也可依此遴选它需要的用户，更便捷在站内建设它需要的文化。 <br />总体来说，豆瓣网非常精巧地应用了div+css，并且通过色系的运用，最大限度减少图片等方式，既使得网站页面清新可人，又可以最大限度压缩网页的大小，从而使得访问的效率得到了最大化。因为页面内几乎没有垃圾信息，从而使得google检索起来都非常有效率，而每页的相关使得网站整体对检索机器人也是非常友好的。 <br />ui布局上，整个网站统一布局，非常容易上手，不容易让用户迷失。豆瓣的ui哲学跟开发者使用python也可能有关系，python是一种通过缩进来进行功能逻辑块的编排，加上python本身的精悍，从而使得python程序非常简约明了。从这个角度说豆瓣布局可以看作python程序的编排，豆瓣的理念也可以看作python的理念。 <br />如果说要问豆瓣网站风格属于什么流派，我想豆瓣应该是属于google的简约派！当然不能说是照搬，毕竟这不同于早期中国网站抄欧美黑乎乎的很商业的风格，近两年抄韩国大色块大图大flash模版的那种做法。我觉得google的简约有四个关键点：简单（够用的功能，包括页面导航）、易用（简单就入手，交互和ui）、体贴（贴近用户心理）、专注（基于业务本身），在此基础上加入自己的网站行业特性。这四点可作为国内web2.0网站重构的参考。 <br /><br />五、 豆瓣技术 <br />由豆瓣的诞生到这一路的发展，其技术一直被认为是网站成功的关键，有趣的是，豆瓣的技术门槛并不高，所以市场上的模仿者层出不穷，但复制豆瓣不代表就能成功，而在豆瓣之前又为什么没人想到类似的构思呢？ <br />豆瓣全部使用python开发。网站后台的搜索引擎基于Twisted, GUI基于Quixote，还用到了cElementTree, MySQL和 PIL，除了这些，豆瓣基本是从头开发（由杨勃一个人四、五个月时间）完成，这是豆瓣技术的基础。纯粹的技术原理之外，相关豆瓣技术还有三个核心原则： <br />（1）以用户为中心 <br />这看上去像是废话式的老生常谈，但在实质应用上，却还是有很多网站抓不住要点，做了很多，但都不是用户想要的。说到底，还是一个观念问题。 <br />Web2.0改变了一些产品特性的优先级。原来做产品，可用性的优先级会往后放，而把功能放在首要位置。现在则由于要给普通用户使用，必须要以用户为中心，肯定要从易用的角度出发了。可以说，Ajax技术的流行，首先解决的也是一个观念问题。虽然这时Pageview无法获得增长，但是它却可以给用户带来更为便利的网络访问。现在的网站开发不是为了追求Pageview了，而是为用户提供需要的功能，满足他们的需求。 <br />豆瓣就是一个代表。创始人杨勃在物理学博士毕业后，曾在IBM公司工作，2000年回国后曾担任一家物流管理软件公司的CTO。不过，热爱编程同时也是书虫的他看到也感受到了人们在书籍、音乐和影视作品分享方面的空缺，从2004年开始设计豆瓣网。 <br />在杨勃看来，对大部分人来说，书籍、音乐、电影的选择特别多，这就带来一个方向，也就是需要发现和分享。每个人的口味都不一样，大家共享之后就会产生口碑传递。“所以，一开始做豆瓣不是为了做一个网站，而是满足人们的一个需求，如果对用户没用，只是新鲜是远远不够的。”  <br />现在同一类型的各个网站技术高低影响不是特别明显，但只需要使用一下网站，就会明白很多差距。为什么豆瓣之前没有相似的构思？为什么众多的跟风者总会感觉差异？创新来自找到需求，细节来自了解需求。 <br />WEB2.0网站技术不需要照抄豆瓣，但从豆瓣建站的出发点，技术人员可以多考虑几种完成项目的方式，思考相互之间有什么不同。大家可以经常问自己这样的问题：这样做会不会给用户带来更多的方便？用户的感受是怎样的？如何做得更好？ <br /><br />（2）简单的前台与复杂的后台 <br />符合用户的习惯，简单的前台界面不代表系统的简单。事实上，正相反，在Web2.0的系统中，后台需要做更多的工作。一些表面看起来很简单的功能背后可能需要大量的程序和计算的支撑。 <br />豆瓣就是最具代表性的例子。与大多数网站不同的是，最早开发的部分是一套推荐引擎，这是基于数学统计的计算模型。在用户点击过看过东西以后，这套模型可以自动分析出“与其口味最像的人”，并主动地推荐用户最有可能喜欢的书籍、音乐或者电影。 <br />豆瓣是100%动态网站，没有一个静态的页面。我们完全可以将其视为一个个人管理书籍、音乐、影碟的工具，只是将工具放在网上了。现在，很多人抄袭了豆瓣的模式和资源，但就如杨勃所言，仅仅抄袭一个网站的表面是没有价值的。“Google的界面更简单，但系统核心不在这里。豆瓣比Tag这些表面的东西多做了一步，采用了统计模型和一些程序算法，事实上，这才是豆瓣网的核心。” <br />Web越来越像一个计算平台。通过各种Web应用将计算机连接起来，比如需要相册时可以使用Flickr，需要地图时调用Google Map的Api。随着很多服务商逐渐将自己的服务开放出来，每个网站都可以视为一个软件服务提供商，相互之间的联系让系统越来越复杂，而这种系统的复杂并不会带来功能使用的繁琐。 <br />强大的功能、简单的使用，这是WEB2.0应用的必然趋势。由豆瓣的应用，可以看出发现联系用户之间的关系，在后台建立导引用户功能的连接，针对数据量做好方便的存储和查询，这些就是网站技术的核心。 <br /><br />（3）快速开发 <br />一个令人难以置信的事实是，豆瓣拥有十多万的注册用户，Alexa的流量排名在一千左右，很长的一段时间内却一直就只有一台八千块钱攒起来的服务器、一两个人的开发团队维护着。 <br />为了适应这种规模，开发模式需要进行改变。这在很多Web2.0的网站中都有所体现，有人称之为简单哲学。为了快速开发，系统设计也需要进行简化。杨勃说，“豆瓣网中间也做过一些变动，最初还是受原来做企业系统的影响，结构设计的太复杂，甚至还分了很多层。后来就简化了，因为太复杂之后就难以做快速开发。” <br />豆瓣现在采用的是敏捷开发的模式，这是一个快速开发、快速变化的体系，平均每两天就有新的功能出现。 <br />“Web2.0网站是快速变化的，并不是把所有的功能都在开始阶段完全实现。”杨勃说，“这就要求系统构架的可扩展性要做的很好。而且必须考虑将来规模可能带来的问题。豆瓣网一开始的架构设计就可以支撑上百万用户。”同时，基于Web的开发省去了客户端分发、维护的成本，因此可以做到“永远的BETA”、随时更新和升级服务。据说，豆瓣学习对象Flickr的升级是以小时为单位的。 <br />Web2.0与用户的交互也是让网站快速完善的动力。网站运行之后，听取用户的反馈，指导下一步的应用开发。“豆瓣网有一个站务论坛，很多人经常发言提出自己的需求。”比如豆瓣刚开张时，由于每个人都可以自由创建小组或者参加小组，于是用户可能会同时参加几十个小组。但由于很多小组人数比较少，可能很长时间才会有人发言，于是大家就要求有一个功能，把所有小组的最新发言聚合在一起。杨勃很快实现了这个功能，事实也证明非常受欢迎。 <br />杨勃认为，由于是小团队，工作模式就不能是一个经理带一帮人，而是大家都需要参与编程。而且，对综合学习能力的要求比较高。“因为技术变化很快，现在对任何技术再熟悉，经验再多，过几个月可能又出现了新的技术，因此最重要的是要能够跟踪最新的知识。而且由于最新的Web2.0模式和思想都是从国外发起的，所以程序员要具有在英文环境中直接沟通的能力，能够直接参与到国外的开源项目中，而不是看已经翻译为中文的文档。”杨勃表示，自己学习Python也是随豆瓣网开始的。“Python很适合敏捷开发，最初的时候曾经尝试过使用Ruby，后来由于豆瓣网需要很多后台的程序，Python更适合编写一些后台模型程序，最终前台也统一为一种语言。”杨勃之前对MySQL了解很少，但在做豆瓣网的过程中，很快将知识弥补上来。“现在我们有几个数据库都可以做同步，有些内容我们还向开源社区进行了回馈。” <br />豆瓣选用了很多开源产品，杨勃认为：“用好开源产品是非常关键的。豆瓣的平台是基于Linux，数据库用的是MySQL，除了数据挖掘和搜索，其它都是在开源产品之上开发的。因为现在有很多非常成熟的产品和模块，没有必要从头做，只要有能力了解获得这方面的知识，都能够很快在别人的基础上开发自己的系统。” <br /><br />六、 人文豆瓣 <br />初来豆瓣的人会发现这里的有效帖子特别多，评论长而且不乏精彩。使用豆瓣的人会发现这里能找到许多冷僻的书、电影、音乐，排在豆瓣排行榜上的大多是与市面畅销流行榜不一样的陌生面孔。豆瓣给人的感觉就是自成一格，评论形容其为“小众”，那些在BLOG中自发传播豆瓣，乐于在豆瓣发布长篇评论的“豆粉”们则将其称为“人文”。 <br />豆瓣是一个全动态页面的网站，通常网站编辑主导的运营方式在这里并不适用，但也不能说豆瓣是一个不做运营，由用户自娱自乐的网站。在豆瓣，运营是一个整体运营的概念，是建站理念、设计、产品、技术架构、文字说明等等所有构成豆瓣的元素共同合力作用出了一个充满人文精神的社区，书是这个社区最有粘合力的纽带。 <br />如果当初杨勃选择电影或音乐作为豆瓣的起点，估计豆瓣的成功尚是未知之数。音乐和电影相对都比较大众，除了那些畅销书和热门书，通常书的阅读更加小众。豆瓣是一个典型的“满足小众需求”的业务模式。在电影和音乐上，人们比较容易找到喜好相近的同伴，但对于书，特别是一本比较冷门的书，找到共同爱好者的机率就比较小。而书又有“圈子阅读”的特性，一本共同喜好的书往往连结的就是两个志趣相投的人，而这批有共同书籍爱好的人基本都有交流的需求，这对“圈子”（小组）的形成是天然的催化剂。 <br />另一方面，喜好阅读的人普遍习惯文字表达和就阅读的书籍留批注，这对豆瓣的评论产生是一个很好的基础。豆瓣最开始是以邮件和在高端的读书类杂志发广告来做推广的，在书这个切入点的前提下，吸引到去豆瓣的第一批用户大多是网上的“”，人群素质比较好，他们又是通过BLOG把豆瓣介绍开来的，看到他们的BLOG的人又成为豆瓣新的用户。这些人普遍使用BLOG，使得这个口碑传播循环能继续下去。 <br />除了找准切入点和用户群外，网站自身的设置也不断强化和促进氛围的形成： <br />1、需求策略：杨勃是读书爱好者，在网站的产品设计上是以满足自身对书的交流分享需求出发的。考虑到需要用户产生内容的网站开始最困难，需要想办法找些基础的内容让用户来参与，然后产生滚雪球效应。为此豆瓣想到的办法是提供比价系统。这个系统实际上是一个搜索引擎，用户可以利用这个搜索引擎找到同一本书在卓越或当当的价格。可以说，现在最能为豆瓣带来实质收入的“比价”在策划推出时间只是一个单纯留住用户的服务，豆瓣首先是一个社区，一个不是以买卖关系为目的，而是以分享阅读体验和结识书友为目的的社区。 <br />而杨勃作为网站的创建人，同时又是网站积极的使用者，抱着永远BETA版的态度对网站做着不间断而频繁的修改，其中用户在豆瓣站务论坛提的意见是一个最重要的意见参考，这保证了网站与用户需求的同步。 <br />2、设计限制：在上文“豆瓣设计”中已经详细说明过，豆瓣的设计风格给人清新的感觉，这是能引起读书人共鸣的设计。相异大多数网站而做的不能贴图的限制，就是源于杨勃觉得豆瓣做书、电影、音乐的评论，主要通过文字表达，图片大概只有5% 的作用。开放贴图，乱七八糟的东西都传了上去，反而降低了网站的素质，那些真正的用户就不再愿意来了。起类似作用的还有跳转页面的用户路径设置，很明显，这里杨勃认为的真正用户就是爱好阅读、习惯文字表达、熟练使用网络的一群人，而这群人的品位和口味自然是有保证的，相对大众流行来说，也就是“小众”。 <br />3、用户引导：在站内的引导文字中，豆瓣不鼓励灌水，不鼓励转载，只希望用户正常使用它。这使得站内用户比较高端，评论比较有效率。 <br />而作为一个社区，豆瓣也没有通常社区网站为增加访问量而设的积分和升级系统。对此，杨勃解释说，“积分问题提过很多次，讨论了很多次，至今还是没有放上去。主要觉得这并不是核心的东西，我们不希望用户是为了积分而来豆瓣，更不希望他们为了积分而灌水，我们需要高质量的帖子和高素质的用户。” <br />以上做法自然会流失很多游客型的用户，但只要留下了，那一定就是只为豆瓣而来的用户，这批用户的忠诚度不言而喻。拥有一定数量的高忠诚度用户是一个社区氛围形成的必备基础，而在上文的分析中也提过，在豆瓣，具号召力的意见领袖和具广泛交际力的传播者都不缺，这也满足了形成社区氛围的条件。 <br />4、语言强化：豆瓣的导引文字亲切而统一，尽量避免技术性语汇和色彩强烈的语言表达，代之以“好了，发言”，“给你的发言起一个标题吧”， “过些天来看看，没准就有了”这些人性化的提示。在图片上传的说明中会给用户一些建议，但最后一句是“当然了，最终还是你自己的决定”，对小组论坛的说明中出现了用户话题不受限制的语句（在不违反法律的前提下不一定局限于小组建立主题），站内倡导的是不同的意见和多样的声音。 <br />“豆邮”是用户的站内联系方式。“豆列”是个人基于某个特定主题的一系列推荐。这两个是官方性质的独创语言符号。而在官方之外，网站更主动收集推广了用户创意的“豆瓣辞典”，如“豆粉”指豆瓣的粉丝，“豆芽”是新注册用户，“黄豆”是资深用户等，这些亲切又另具新意的词汇形成了豆瓣独特的语言体系。 <br />豆瓣还有个栏目叫“15分钟名组”，是推荐给用户的小组，从所有小组里随机挑选。每15分钟更新一次。名称来自英语俗语——“15 minutes of fame”， 意思是每个人都有机会出名，但往往名气片刻即逝。这样的典故型命名，是需要有一定文化背景才能领会的。而由以上提及语言构成的站内语境对氛围的形成起的是潜移默化的作用。  <br />共同主题、意见领袖、独特的语言体系，这是形成社区氛围的三大条件，从上文对豆瓣的分析，这些要素豆瓣都已经通过网站的整体运营具备了。配以网站“书”的切入点，聚拢的高质用户群，一个人文的豆瓣自然形成了，而这些都是照抄豆瓣网站模式不能搬走的豆瓣价值。 <br /><br />七、 豆瓣所学 <br />豆瓣不是一个公益机构，我相信豆瓣一定会走上资本介入的商业网站道路。但豆瓣现在这种小众而缓慢的用户群积累，从时间成本和网站定位上，与碰碰的策略都没有可比之处。从上面的分析可见，就算照抄出一个一模一样的豆瓣，在市场上的成功预期也未见就理想。但从豆瓣网站架构和运营上，碰碰也可以思考一些学习点： <br />人与物之间的关系体现：豆瓣是一个有SNS元素的网站，运营现状上，对“物”的体现是压倒“人”的。碰碰是一个兴趣交友网站，“人”是突出的一环，个人展现和兴趣圈都是以“人”为核心的。但两者在交友上的共同点都是用“物”做媒介的，豆瓣是书、电影、音乐，碰碰是兴趣。 <br />豆瓣抓住了人对书、电影、音乐的分享交流需求设置产品，进一步来说，是以评论/评价作为“人”对“物”的作用过程，以收藏作为“人”对“物”作用的结果。而碰碰呢？16个兴趣圈的功能设置都是一致的，难道“人”参与所有兴趣的过程和结果都是一样的吗？ <br />现阶段要求所有兴趣圈都有不同的功能体现是不太现实的，但在重点兴趣圈或用户作用点相似的兴趣圈类别特别设置满足该兴趣用户需求的参与产品，让参与该兴趣圈类别的用户能在个人展现部分体现他参与的结果，这不但打通了兴趣圈与个人展现之间的渠道，也是兴趣圈能最终达致垂直型运营的途径。 <br /><br />站内个体用户间的关联：豆瓣是通过物做人的媒介的，碰碰的“人”和“兴趣”就如同豆瓣的“人”和“物”（书、电影、音乐），是以“兴趣”做人的媒介。 <br />豆瓣友邻中显示的是其他用户对“读、看、听”的状态——“过、在、想”，对“人”多设置了一重对“物”的状态显示，实质就是在人人关系间再多加了一个纬度的表述。这比碰碰单纯的人人关系间只拥有共同“兴趣”是一种更趋近的用户联系，推动用户交流的作用更明显。 <br />豆瓣就有不少用户认为，比起网站推荐的“豆瓣猜你会喜欢”，友邻标识过的产品更有吸引力，而在某个产品的欣赏时期，发现另一个人与自己在同一状态，寻求讨论的欲望也更加强烈。就像其他交友网站会依据用户各自站内好友间的关系列出用户之间的亲密指数，会根据血型、星座等给出用户间的共同点似的，这是标识用户间更密切的联系激发用户的交友冲动。 <br />碰碰在个人展现上需要多考虑的是挖掘用户间的更紧密联系，这种挖掘不是靠用户主动提供、主动寻找的，而是网站通过后台数据的关联直接标识给用户的，用户资料、用户行为、人际关系都是可以挖掘标识的点。 <br /><br />站内群用户之间的关联：豆瓣群与群之间的关联是共同参加的人（“成员常去的其他小组”），是在每个小组页面都有明显标识的，这样的交友导引是从一群人认识一群人，比单纯搜索小组增加了用户流动的途径。 <br />除了同一个类别/圈主，碰碰的圈子之间是没有紧密联系的。对应豆瓣的做法，同一圈主创建的圈子、参与成员也去的圈子、同一类别新成立/推荐圈子、与圈子举办过同类型活动的圈子……这些都可以体现在圈子内，辅以圈子间互动的产品，圈子间运营和圈子间用户的流动会更畅通，关键是要找到圈子之间的共同点。 <br /><br />提供用户实质用途的服务：这个所谓实质用途不单是从网站自身经营目的考虑，最重要的还是从用户日常生活考虑。就好像IM用户的高粘着度是满足用户日常通讯需求而来，豆瓣用户也有不少是为了豆瓣的收藏功能而来的。他们不热衷交友，评论是多看少写，购买参考是零星行为，豆瓣对于他们只是一个整理自己图书、电影、唱片的架子。不少BLOG也有类似作用的自设列表功能，但豆瓣的内涵更丰富（涵盖了产品的所有信息），操作却更简单（一个标识动作），服务也更贴心（可循三种方式排序、可以标签整理），于是成为了有此需求用户的首选，其他的BLOG反倒沦为豆瓣推广的途径。 <br />与此相似的还有豆瓣提供的一站式网上书店搜索功能，这都是对用户实用、能带来高粘着度的产品，特别对于刚起步的网站更是需要。碰碰在这方面的产品是欠缺的。 <br /><br />社区氛围营造：在豆瓣是整体运营的概念，是运营策略、产品架构、网站细节合力的结果。碰碰要学习的关键点是整体和细节，社区氛围不应该只是运营部的任务，而应该是所有部门合力的成果。对细节的关注参考上文“人文豆瓣”中分析。 <br /><br />用户沟通反馈：豆瓣的站务论坛起的就是与用户直接沟通的作用，除了客服，碰碰2.0也有直接与用户沟通的编辑圈，此外编辑还有与用户联络的，数起来，碰碰与用户的联系方式比豆瓣还略胜一筹。但在用户意见的反馈上，特别是涉及技术的产品优化的意见上，碰碰的行动力比起豆瓣就不止慢一拍半拍了。从上文“豆瓣技术”的分析，豆瓣的反馈速度与豆瓣的敏捷开发模式相关，技术的同事可考虑借鉴其中碰碰可运作的点，提升碰碰产品因应用户意见优化的速度。 <br /><br />用户需求的线上线下结合： <br />“豆瓣猜您会喜欢某书，因为您3个月来阅读的内容与此书相关，而且与您口味相同的好友XXX对此书评价甚高（点击参考他的评论），另外还有与您兴趣口味相类似的XXX人对此书作出正面评价（点击观看这些都是些什么人），如果您有兴趣请在方便的时候到离您最近的XX书店（点击观看地图）翻阅，他们尚有XXX本存货，此外豆瓣还提供10多家网络书店的比价（点击进入）。……” <br />以上是IT评论家对豆瓣理想模式的描述，如果真的有上面的信息，那么说明豆瓣已经拥有了：1、聚合用户习惯进行比较分析的能力，2、根据以上分析聚合用户SN中相关评论的能力，3、根据推荐内容分析聚合相关微内容的能力，4、与地面渠道实时结合交互的能力，5、与线上渠道结合交互的能力；在拥有这些能力的基础上，即便不向下游用户收费也可以真正提高豆瓣的议价能力而且这种模式不容易被复制——用户的消费习惯阅读习惯不是靠填写几张调查表或者分析几张订单就能搞定的，豆瓣有着比较忠诚的用户群，也有着相对容易的分析条件，建立这样一个CRM系统不应该是件难事，假以时日，在这个系统上进行营销、无论是线上还是线下，都将是别人无法复制的豆瓣，很简单，复制者就算有更多的钱和更多的人去复制豆瓣，但他们始终无法复制一个相对比较长的时间长度，一个人的365天和365个人的一天，显然是前者对豆瓣这样专注于某个领域的网站更有价值，也不是复制者在朝夕之间可以复制的。
          <br/>
          <span style="color:red;">
            <a href="http://weskycn.javaeye.com/blog/127214#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 26 Sep 2007 10:34:09 +0800</pubDate>
        <link>http://weskycn.javaeye.com/blog/127214</link>
        <guid>http://weskycn.javaeye.com/blog/127214</guid>
      </item>
      <item>
        <title>三种方式（div＋css）轻松搞定圆角矩形</title>
        <author>weskycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://weskycn.javaeye.com">weskycn</a>&nbsp;
          链接：<a href="http://weskycn.javaeye.com/blog/125064" style="color:red;">http://weskycn.javaeye.com/blog/125064</a>&nbsp;
          发表时间: 2007年09月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          三篇外文，仔细研究，很方便！<br /><a href="http://www.modxcms.com/simple-rounded-corner-css-boxes.html" target="_blank">Simple Rounded Corner CSS Boxes</a><br /><a href="http://www.spiffybox.com/index.php" target="_blank">spiffybox</a><br /><a href="http://www.spiffycorners.com/index.php" target="_blank">spiffycorner</a>
          <br/>
          <span style="color:red;">
            <a href="http://weskycn.javaeye.com/blog/125064#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 18 Sep 2007 17:21:00 +0800</pubDate>
        <link>http://weskycn.javaeye.com/blog/125064</link>
        <guid>http://weskycn.javaeye.com/blog/125064</guid>
      </item>
      <item>
        <title>活用插件attachment_fu，在rails中以AJAX方式上传文件</title>
        <author>weskycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://weskycn.javaeye.com">weskycn</a>&nbsp;
          链接：<a href="http://weskycn.javaeye.com/blog/123777" style="color:red;">http://weskycn.javaeye.com/blog/123777</a>&nbsp;
          发表时间: 2007年09月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          这篇文章主要解决的问题是用attachment插件和responds_to_parent插件实现ajax方式上传文件（图片）的目的。<br /><strong>Step 1. Choose a file upload plugin（选择上传插件）</strong><br />可用的上传插件有如下三种：<br />[list=]1.file_column <br />2.acts_as_attachment <br />3.attachment_fu [/list]<br />推荐attachment fu＋rails1.2.<br /><strong>Step 2. 选择安装Rmagic </strong><br /><pre name="code" class="java">gem install rmagic</pre><br /><strong>Step 3. 新建项目并下载插件attachment_fu</strong><br />新建项目demo<br /><div class="quote_title">引用</div><div class="quote_div">rails demo</div><br />安装插件attachment_fu:<br /><div class="quote_title">引用</div><div class="quote_div">cd demo<br />ruby script/plugin install http://svn.techno-weenie.net/projects/plugins/attachment_fu/</div><br /><strong>Step 4. 开始编写代码</strong><br />用下面命令创建一个rails资源asset<br /><div class="quote_title">引用</div><div class="quote_div">ruby script/generate scaffold_resource asset filename:string content_type:string size:integer width:integer height:integer parent_id:integer thumbnail:string created_at:datetime</div><br />下面是自动生成的migration，可自行修改，在此我们使用默认。<br /><pre name="code" class="java">
class CreateAssets &lt; ActiveRecord::Migration
  def self.up
    create_table :assets do |t|
      t.column :filename, :string
      t.column :content_type, :string
      t.column :size, :integer
      t.column :width, :integer
      t.column :height, :integer
      t.column :parent_id, :integer
      t.column :thumbnail, :string
      t.column :created_at, :datetime
    end
  end

  def self.down
    drop_table :assets
  end
end
</pre><br /><strong>在模型中，我们加入以下代码：</strong><br /><pre name="code" class="java">class Asset &lt; ActiveRecord::Base
  has_attachment  :storage => :file_system, 
                  :max_size => 1.megabytes,
            :thumbnails => { :thumb => '80x80>', :tiny => '40x40>' },
                                    :processor => :Rmagick 
end</pre><br /><br /><strong>Step 5. AJAX it</strong><br />把Javascript prototype/scriptaculous 加入layout.<br /><pre name="code" class="java">&lt;%= javascript_include_tag "prototype", "effects", "application" %></pre><br /><strong>安装插件responds_to_parent</strong><br /><pre name="code" class="java">ruby script/plugin install http://sean.treadway.info/svn/plugins/responds_to_parent/</pre><br /><strong>修改index.rhtml:</strong><br /><pre name="code" class="java">&lt;% form_for(:asset, :url => formatted_assets_path(:js), 
            :html => { :multipart => true, 
            :target => 'upload_frame'}) do |form| %>
&lt;%= render(:partial => '/assets/form', : object => form) %>
&lt;% end %>
&lt;iframe id='upload_frame' name="upload_frame" style="width:1px;height:1px;border:0px" src="about:blank">&lt;/iframe>
&lt;ul id="assets">
&lt;% @assets.each do |a|%>
&lt;%= render(:partial => '/assets/list_item', : object => a)%>
&lt;% end %>
&lt;/ul></pre><br /><strong>新建一个局部模版文件_form.rhtml:</strong><br /><pre name="code" class="java">&lt;p>
    &lt;label for="uploaded_data">Upload a file:&lt;/label>
    &lt;%= form.file_field :uploaded_data %>
  &lt;/p>
  &lt;p>
    &lt;%= submit_tag "Create" %>
&lt;/p></pre><br /><strong>新建一个局部模版文件_list_item.rhtml:</strong><br /><pre name="code" class="java">&lt;li id="asset_&lt;%= list_item.id %>">
&lt;%= link_to(image_tag(list_item.public_filename(:thumb))) %>&lt;br />
&lt;/li></pre><br /><strong>修改assets_controller.rb中的create方法如下：</strong><br /><pre name="code" class="java">  def create
  @asset = Asset.new(params[:asset])
  respond_to do |format|
    if @asset.save
      flash[:notice] = 'Asset was successfully created.'
      format.html { redirect_to asset_url(@asset) }
      format.xml  { head :created, :location => asset_url(@asset) }
      format.js do
        responds_to_parent do
          render :update do |page|
            page.insert_html :bottom, "assets", :partial => '/assets/list_item', : object => @asset
            page.visual_effect :highlight, "asset_#{@asset.id}" 
          end
        end          
      end
    else
      format.html { render :action => "new" }
      format.xml  { render :xml => @asset.errors.to_xml }
      format.js do
        responds_to_parent do
          render :update do |page|
              # update the page with an error message
          end
        end          
      end
    end
  end
end</pre><br /><strong>最后别忘了，修改config文件夹中的database.yml文件，创建相应的数据库，并执行命令：</strong><br /><pre name="code" class="java">rake db:migrate
ruby script/server</pre><br /><strong>然后到浏览器里面查看效果吧！<br /><br />注：本文翻译自<a href="http://khamsouk.souvanlasy.com/" target="_blank">http://khamsouk.souvanlasy.com/</a>。更详细的介绍请访问原文。另外本篇所介绍的内容经过测试没有问题。欢迎讨论交流</strong>
          <br/>
          <span style="color:red;">
            <a href="http://weskycn.javaeye.com/blog/123777#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 14 Sep 2007 13:35:00 +0800</pubDate>
        <link>http://weskycn.javaeye.com/blog/123777</link>
        <guid>http://weskycn.javaeye.com/blog/123777</guid>
      </item>
      <item>
        <title>把已有项目整合beast，共用beast里的users表，舒服啊</title>
        <author>weskycn</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://weskycn.javaeye.com">weskycn</a>&nbsp;
          链接：<a href="http://weskycn.javaeye.com/blog/120750" style="color:red;">http://weskycn.javaeye.com/blog/120750</a>&nbsp;
          发表时间: 2007年09月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-family: Arial">把已有项目整合beast，共用beast里的users表，舒服啊。</span></p><p>推荐大家看这篇两篇文章，<span style="font-family: Arial"><a href="http://programmerassist.com/article/302">http://programmerassist.com/article/302</a>和<span style="font-family: Arial"><a href="http://blog.aisleten.com/2007/07/04/integrating-beast-forum-into-a-ruby-on-rails-app-part-1/">http://blog.aisleten.com/2007/07/04/integrating-beast-forum-into-a-ruby-on-rails-app-part-1/</a></span></span></p><p>今天要下班回家了，明天仔细研究下发布出来。</p><p>&nbsp;</p><p>At some point, it&rsquo;s almost guaranteed that you will want a forum for your website. Forums make a great way to allow your users to contact you and each other, and their persistence allows for archiving of the answers so you (hopefully) don&rsquo;t have to keep answering the same questions over and over. Moreover, most users are familiar with the forum concept and interface, thereby reducing the barrier to communication.</p><p>If all you want is to get a forum up as fast as possible, there are <a href="http://www.forummatrix.org/"><span style="color: #cc6600">several free/open-source/commercial solutions</span></a>. They will get you up and running very quickly, provide all the functionality you need, plus tons of features you&rsquo;ll probably never use. If that&rsquo;s what you want, stop reading and go get one.</p><p>Assuming you&rsquo;re still here, then you&rsquo;re probably in the same boat as me. You&rsquo;ve got a pre-existing Ruby on Rails application, and you want to add a forum. Moreover, you want to add an <em>integrated</em> forum that allows your users to utilize the same login credentials as they use for your current app.</p><p>Enter the <a href="http://beast.caboo.se/"><span style="color: #cc6600">Beast</span></a>! Beast is a pure RoR forum application that has everything you might expect from a forum, plus offers the glimmer of hope that you&rsquo;ll be able to integrate it with your current app. Still, once you dive in, the glimmer starts looking pretty dim. I approached it several times and backed off before I finally had the confidence to finish it. Luckily for others, I made a lot of mistakes and am happy to share them.</p><h2>The Goal</h2><p>For now, my only goal is to unify usernames and passwords, preventing the users from having to register twice. Very important to note is the fact that I am NOT talking about a single sign-on. I am comfortable (at this point) with forcing the user to sign in twice. I simply want to make sure that the username and password are the same both times. Remember: <a href="http://en.wikipedia.org/wiki/KISS_principle"><span style="color: #cc6600">KISS</span></a> and baby steps.</p><h2>Before you start</h2><p>Before I describe the actual approaches, I would like to give some general advice on how to proceed, regardless of your approach. These following tips could potentially save you a lot of time in the very real case that something goes horribly wrong.</p><h3>Create a development branch</h3><p>You are about to attempt a potentially nasty bit of integration. You might need to hack your code (and Beast&rsquo;s code) in very ugly ways. You may need to compromise your whole design. Worst of all, you might fail! At the end, you may realize that it just is not worth it, and you&rsquo;re destabilizing your codebase too much to justify the payoff. Wouldn&rsquo;t it be nice to simply write off the time and get back to work?</p><p>From another angle, perhaps you&rsquo;re in the middle of the integration when a user finds a nasty bug on your live site. You need to fix the bug right now, but your codebase is in a totally unstable state. You can&rsquo;t fix the bug without checking in your Beast changes, and they will break everything. Sounds like it&rsquo;s going to be a long night&hellip;</p><p>If you do your work on a development branch, then switching back to the trunk is very easy. Simply check in all your changes on the branch, then wipe out your working copy and check out a fresh one from the trunk. All the work you did on Beast is still there (in the branch), but you&rsquo;re working on the trunk, totally clean. You can continue main development (such as fixing nasty bugs), and get back to Beast when time allows. Finally, when you&rsquo;re satisfied that Beast is ready, a simple merge-to-trunk is all it takes to bring all your changes into the trunk.</p><p><strong>Bottom line:</strong> Do all your Beast integration work on a branch.</p><h3>Grab Beast as a vendor branch</h3><p>Beast is still under active development, and they just hit 1.0 Do you plan to stay current with it as it matures over time? I definitely plan to. However, integrating it with your application will almost definitely require you to modify it in some way. Heck, just installing it by itself will probably require modifications in order to get the text to say what you want.</p><p>Starting from a vendor branch will allow you to (hopefully) easily upgrade to newer versions, while keeping all the changes you had to make in order to get it working with your app.</p><p>We have already covered <a href="http://blog.aisleten.com/2007/03/02/use-vendor-branches-for-plugins-not-scriptplugin-install/"><span style="color: #cc6600">how to do a vendor branch</span></a> and <a href="http://blog.aisleten.com/2007/05/18/subversion-vendor-branches-in-action-going-from-07-to-085-of-acts_as_solr/"><span style="color: #cc6600">how to upgrade using a vendor branch</span></a>, so go browse those posts if you don&rsquo;t know what I&rsquo;m talking about.</p><p>Please, I&rsquo;m begging you, trust me on this one. Do the vendor branch and save yourself a huge headache when Beast 1.1 comes out&hellip;</p><h2>The Approaches</h2><p>I attacked the integration problem from three different angles. Two worked and one was a total failure. I&rsquo;ll describe each one and its pros and cons. If I get anything wrong, or left something out, please do not hesitate to correct me in the comments. I really want this to be a valuable resource for the Rails community.</p><p>One commonality to note between all the approaches was that I never tried to fully integrate the applications from the perspective of controllers and routing. They each retained their own directory structure, they each will have their own root domain, and they will each require their own mongrel server, unless I can figure out how to get a single mongrel to serve both.</p><h3>1. Separate databases; Users pulled from my app&rsquo;s database</h3><p>With this approach, I tried to keep separate the two databases, except for the Users. The <a href="http://api.rubyonrails.org/classes/ActiveRecord/Base.html"><span style="color: #cc6600">RDocs for ActiveRecord::Base</span></a> give instructions on how to force Rails to connect to a different database for a specific model. This seemed like an excellent way to handle the Beast integration.</p><p>I added all the missing Beast user columns to my Users table, created the secondary database, and updated the Beast User model to connect to my database. At first it worked, and I was pretty excited. However, as I navigated around the forums, it crashed almost immediately. Because there are several relationships between the User and other models, the system was attempting to run some joins. Perhaps other RDBMS&rsquo;s can do cross-database joins, but it seems that MySQL cannot, at least not how I have it set up.</p><p><strong>Bottom line:</strong> Didn&rsquo;t work because MySQL freaked out about the cross-database joins.</p><h3>2. Same databases; Beast tables renamed with beast_</h3><p>My second attempt involved adding all the Beast tables to my current database, and then renaming all the Beast tables with a &ldquo;beast_&rdquo; prefix. It wasn&rsquo;t strictly necessary as there were no naming conflicts, but I thought it would help with readability.</p><p>I left the users table and sessions tables untouched, as I already had a users table and simply added the Beast columns to it. The sessions table seemed like something special, so I decided not to mess with it.</p><p>To accomplish the renaming, all I had to do (I thought) was edit the migrations a little, then use the set_table_name directive in each of the model classes. When this was done, things looked like they would work.</p><p>What I didn&rsquo;t realize was that much of the Beast database querying is done via specifying :conditions on a find() call. I didn&rsquo;t look too closely, but perhaps the Beast team found they could not be served adequately by the find_by_x_and_y finders. The end result of this was that there were several places where the table names were listed explicitly inside the query conditionals. I ran several search/replace runs for &ldquo;posts&rdquo;, &ldquo;forums&rdquo;, and so on for all the Beast tables. Of course, these strings got several hundred hits throughout the codebase, and the replacement was a real chore.</p><p>Eventually I got Beast working, but I did not have a lot of confidence in the changes. I was not sure if I had caught everything, although this could be reasonably tested using the unit and functional tests. Most troubling to me, however, was the prospect of trying to integrate a new release. I had the sneaking suspicion that every time there was a new release of Beast, I would be hunting down table names inside of conditionals and replacing them by hand. Besides the tediousness, this was bound to produce bugs that I wouldn&rsquo;t catch and would escape into production.</p><p><strong>Bottom line:</strong> Works, but you&rsquo;re in for a world of hurt when you want to upgrade to a new release of Beast.</p><h3>3. Same database; Beast tables unmodified</h3><p>As I mentioned earlier, I had no table name conflicts with Beast