The 10 Most Underused ActiveRecord::Relation Methods

2013年11月12日 14:26

10. first_or_create with a block

first_or_create is very familiar:

Book.where(:title => 'Tale of Two Cities').first_or_create

Often, though, you want to find a record with certain attributes, or create one with those and additional attributes. To do this succinctly, you can supply a block to first_or_create:

Book.where(:title => 'Tale of Two Cities').first_or_create do |book|
  book.author = 'Charles Dickens'
  book.published_year = 1859
end

9. first_or_initialize

If you don’t want to save the record yet, you can use first_or_initialize:

Book.where(:title => 'Tale of Two Cities').first_or_initialize

继续阅读 »

关于MongoDB你需要知道的几件事

2013年11月12日 13:45

用MongoDB也快半年了,今天突然看到关于MongoDB你需要知道的几件事,很有感触,顺便记录下来。

消耗磁盘空间

MongoDB会消耗太多的磁盘空间了。当然了,这与它的编码方式有关,因为MongoDB会通过预分配大文件空间来避免磁盘碎片问题。它的工作方式是这样的:在创建数据库时,系统会创建一个名为[db name].0的文件,当该文件有一半以上被使用时,系统会再次创建一个名为[db name].1的文件,该文件的大小是方才的两倍。这个情况会持续不断的发生,因此256、512、1024、2048大小的文件会被写到磁盘上。最后,再次创建文件时大小都将为2048Mb。如果存储空间是项目的一个限制,那么你必须要考虑这个情况。该问题有个商业解决方案,名字叫做TokuMX,使用后存储消耗将会减少90%。此外,从长远来看,repairDatabase与compact命令也会在一定程度上帮到你。

通过复制集实现的数据复制效果非常棒,不过也有限制

MongoDB中数据复制的复制集策略非常棒,很容易配置并且使用起来确实不错。但如果集群的节点有12个以上,那么你就会遇到问题。MongoDB中的复制集有12个节点的限制,这里是问题的描述,你可以追踪这个问题看看是否已经被解决了。

主从复制不会确保高可用性

尽管已经不建议被使用了,不过MongoDB还是提供了另外一种复制策略,即主从复制。它解决了12个节点限制问题,不过却产生了新的问题:如果需要改变集群的主节点,那么你必须得手工完成。

不要使用32位版本

MongoDB的32位版本也是不建议被使用的,因为你只能处理2GB大小的数据。

咨询费非常非常昂贵

差劲的管理工具

这对于初学者来说依然是个让人头疼的问题,MongoDB的管理控制台太差劲了。我所知道的最好的工具是RoboMongo,它对于那些初次使用的开发者来说非常趁手。

了解官方的限制

继续阅读 »

How to start an SVN project from the command line?

2013年11月07日 14:01

cd [my project dir]
svn import -m "First Check-in" [SubversionRunningMachine]/[ProjectName]/[my project dir]
cd ..
svn co [SubversionRunningMachine]/[ProjectName]/[my project dir] [my project dir]

继续阅读 »

MyEclipse里编辑的项目名的红叉,怎么解决

2013年11月06日 18:25

症状:

一般出现在从别处import的项目上,只有项目文件夹上有红叉,其他地方都正常

解决办法:
1,编码设置是否一致,也即是你项目原来的编码和现在eclipse用的默认编码是否一致
2,导入项目中jar路径可能已经被改变,多数情况下都是这个原因造成,我也曾经遇见过,你要确保你的jar包路径都没问题。myeclipse有查看jar路径的视图你可切换看看,报红X的就都是路径被改动过的,重新加进来就OK。
3,在problem控制台里有如下错误提示:Java compiler level does not match the version of the installed Java project facet。这种情况一般可以在项目上右键-->properties-->然后找到project facets和 Java Compiler两个选项,修改其使用的jdk版本即可。

继续阅读 »

新增了纵横中文网《不败战神》抓取

2013年11月04日 23:35

不败战神 抓取

# encoding: utf-8
require 'rubygems'
require 'nokogiri'
require 'open-uri'

class Zongheng

  def self.start
    urls = {
      "不败战神" => "http://book.zongheng.com/showchapter/251393.html"
    }
    start_time = Time.now.to_s
    begin
      urls.each_pair do |name, val|  
        get_chapter_list(name,val)
      end
    rescue Exception => e
      Rails.logger.error "fetch zongheng had a Exception"+e.to_s
    end
    Rails.logger.info "Zongheng end>>>>start_time="+start_time+">>>>end_time="+Time.now.to_s
  end

  def self.get_chapter_list name,base_url
    f = i_open base_url
    return "" unless f
    titles = Nokogiri::HTML(f).css("div.booklist td a")
    titles[-2..-1].each do |title|
      post_content = get_post_content title['href']
      if post_content && post_content.length>100
        # 有内容  则入库,标题,章节内容,小说名,
        novel = Novel.where(:name => name).first_or_create
        chapter = Chapter.where(:name => title.text).first_or_create(:content => post_content,:novel => novel)
        if post_content.length != chapter.content.length
          chapter.content = post_content
          chapter.save
        end
      end
    end
  end

  def self.get_post_content url
    # p url
    f = i_open url
    return "" unless f
    post_content = Nokogiri::HTML(f).css("#chapterContent");
    # 去掉无用链接
    post_content.css(".watermark").remove
    post_content.css("a").remove
    post_content.inner_html.encode("utf-8")
  end

  def self.i_open url
    begin
      open(url,:read_timeout=>20)
    rescue Exception => e
      return nil
    end
  end

end

继续阅读 »

Using Ruby's Gsub With a Hash

2013年10月18日 17:52

def geekify(string)
  string.gsub(/[leto]/, 'l' => '1', 'e' => '3', 't' => '7', 'o' => '0')
end

geekify('leet') # => '1337'
geekify('noob') # => 'n00b'
def doctorize(string)
  string.gsub(/M(iste)?r/, 'Mister' => 'Doctor', 'Mr' => 'Dr')
end

doctorize('Mister Freeze') # => 'Doctor Freeze'
doctorize('Mr Smith')   # => 'Dr Smith'

继续阅读 »

把全站都改成了page_cache方式了

2013年9月13日 12:28

1.文章时间改成具体的发布时间
2.分页route做了修改
3.nginx配置做了修改,把所有cache的文件都放到了caches里了

# Index HTML Files
if (-f $document_root/cache/$uri/index.html) {
  rewrite (.*) /caches/$1/index.html break;
}

# HTML Files
if (-f $document_root/cache/$uri.html) {
  rewrite (.*) /caches/$1.html break;
}

# Catch all
if (-f $document_root/cache/$uri) {
  rewrite (.*) /caches/$1 break;
}

继续阅读 »

Ruby tap method

2013年8月26日 22:32

tap定义

class Object 
  def tap 
    yield self 
    self 
  end 
end

Usage

1
blah.sort.grep( /foo/ ).map { |x| x.blah }
xs = blah.sort.grep( /foo/ )
p xs

# do whatever we had been doing with the original expression
xs.map { |x| x.blah }
blah.sort.grep( /foo/ ).tap { |xs| p xs }.map { |x| x.blah }

继续阅读 »

A Rails API Pattern for Complex Collections

2013年8月26日 22:15

def index
  @recipe_collection = RecipeCollection.from_params(params)
  render json: @recipe_collection.recipes
end
class RecipeCollection
  attr_accessor :featured, :time_filter

  # Handles the logic of sorting params into a collection
  def self.from_params(params)
    RecipeCollection.new.tap do |recipe_collection|
      recipe_collection.time_filter = params[:time_filter]
      recipe_collection.featured = params[:featured]
    end
  end

  # Should return an ActiveRecord relation
  def recipes
    query = Recipe.scoped
    query.featured if featured.present?
    query.filter_by_time(time_filter)
  end

  def time_filter
  valid_time_filters.include?( @time_filter ) ? @time_filter : default_time_filter
  end

  def default_time_filter
    "today"
  end

  def valid_time_filters
    %w[ today yesterday this-week this-year ]
  end
end

继续阅读 »

Incremental Redesign with Rails

2013年7月31日 17:15

重构前

<%- if current_user.redesign_enabled? %>
  <%# new code %>
<%- else %>
  <%# old code %>
<%- end %>

重构后

class ApplicationController < ActionController::Base
  before_filter :add_view_path_for_redesign

  private

  def add_view_path_for_redesign
    if current_user.redesign_enabled?
      prepend_view_path Rails.root.join('app/views/redesign')
    end
  end
end
# original
app/views/users/edit.html.erb
app/views/users/show.html.erb

# redesign
app/views/redesign/users/edit.html.erb
app/views/redesign/users/show.html.erb

继续阅读 »