给 Octopress 加上标签功能

上周,我将 Log4D 由 WordPress 转换为 Octopress,略加打理,颇为顺手。 自动分类 / 评论转移 / 代码高亮 / 图床 的问题一一解决之后, 就只剩下 tag 的问题没有搞定了。

我当时使用了YORKXIN的修改版本来处理 WordPress 的数据迁移,这个脚本很好用,数据没有遗失,甚至是让我担心的 category / tag 都给予了保留。具体使用方法可以参见从Wordpress迁移到Octopress。

只是虽然 tag 的数据保留了,但是 Octopress 仅支持 category 的分类,而完全忽略 tag。这是我不能容忍的:category 和 tag 分别代表 有序 / 无序 的知识点归纳方法。 一篇文章只能属于一个 category,但可以同时属于多个 tag。 Octopress 的设计方法显然和我长期养成的知识归纳体系冲突,我开始吭次吭次寻找插件。

ps:Octopress 官方也推荐了一个所谓「octopress-tagcloud」的插件, 但这仅仅是让 category 用 列表 / 标签云的形式展示出来,并没有给文章加入 tag 概念。更多官方插件可以查看 3rd party plugins。

就在我准备放弃,自己动手用蹩脚的 ruby 水平写插件时候,突然在 github 找到这种插件: robbyedwards / octopress-tag-pages和 robbyedwards / octopress-tag-cloud。前者负责采集文章的 tag 信息,后者提供标签云展示功能。赞美 Github。

这两个插件使用很简单,将插件文件放入对应的目录(注意备份,存在覆盖的情况)。 然后再给插件「octopress-tag-cloud」添加一个专属页面存放标签云即可。 这个标签云生成的标记是 li…li ,需要在 sass/custom/_styles.scss 添加对应的样式:

#content article .cloud li{
display: inline;
list-style: none outside none;
padding: 0 4px;
}
第二个插件 octopress-tag-cloud 会和 Octopress 官方推荐的所谓「Octopress Tag Cloud」 文件 / tag 标记 冲突,我建议修改官方的那个插件。

我修改过的 octopress-tagcloud 在这里,被重命名为 alswl / octopress-category-list。

这个版本同时参考了 pf_miles 的 utf-8 修改,以修复问题 Liquid error: incompatible encoding regexp match (ASCII-8BIT regexp with UTF-8 string) 。

最后 Show 一下我的一坨标签云, 等有时间我再将标签和类别精简一下,以适应 Octopress。

版权所有 © 2010 转载本站文章请注明: 转载自 Log4D
原文链接: http://log4d.com/2012/05/tag-cloud/
您可以随意地转载本站的文章,但是必须在醒目位置注明来源及本站链接,不可以将本站文章商业化使用,或者修改、转换或者以本作品为基础进行创作。

Posted in Uncategorized

通过mongodump和mongorestore实现Mongodb备份和恢复 –by chenzhou123520

from http://chenzhou123520.iteye.com/blog/1630993

Mongodb自带了mongodump和mongorestore这两个工具来实现对数据的备份和恢复。

mongodump能够在Mongodb运行时进行备份,它的工作原理是对运行的Mongodb做查询,然后将所有查到的文档写入磁盘。但是存在的问题时使用mongodump产生的备份不一定是数据库的实时快照,如果我们在备份时对数据库进行了写入操作,则备份出来的文件可能不完全和Mongodb实时数据相等。另外在备份时可能会对其它客户端性能产生不利的影响。

mongodump用法如下:

[root@localhost mongodb]# ./bin/mongodump --help
Export MongoDB data to BSON files.

options:
  --help                   produce help message
  -v [ --verbose ]         be more verbose (include multiple times for more
                           verbosity e.g. -vvvvv)
  --version                print the program's version and exit
  -h [ --host ] arg        mongo host to connect to ( <set name>/s1,s2 for
                           sets)
  --port arg               server port. Can also use --host hostname:port
  --ipv6                   enable IPv6 support (disabled by default)
  -u [ --username ] arg    username
  -p [ --password ] arg    password
  --dbpath arg             directly access mongod database files in the given
                           path, instead of connecting to a mongod  server -
                           needs to lock the data directory, so cannot be used
                           if a mongod is currently accessing the same path
  --directoryperdb         if dbpath specified, each db is in a separate
                           directory
  --journal                enable journaling
  -d [ --db ] arg          database to use
  -c [ --collection ] arg  collection to use (some commands)
  -o [ --out ] arg (=dump) output directory or "-" for stdout
  -q [ --query ] arg       json query
  --oplog                  Use oplog for point-in-time snapshotting
  --repair                 try to recover a crashed database
  --forceTableScan         force a table scan (do not use $snapshot)

参数说明:

-h:指明数据库宿主机的IP

-u:指明数据库的用户名

-p:指明数据库的密码

-d:指明数据库的名字

-c:指明collection的名字

-o:指明到要导出的文件名

-q:指明导出数据的过滤条件

具体使用示例如下:

[root@localhost mongodb]# ./bin/mongodump -d test -o data/backup
connected to: 127.0.0.1
DATABASE: test	 to 	data/backup/test
	test.system.indexes to data/backup/test/system.indexes.bson
		 9 objects
	test.users to data/backup/test/users.bson
		 3 objects
	test.games to data/backup/test/games.bson
		 1 objects
	test.blog.post to data/backup/test/blog.post.bson
		 1 objects
	test.lists to data/backup/test/lists.bson
		 1 objects
	test.math to data/backup/test/math.bson
		 1 objects
	test.map to data/backup/test/map.bson
		 8 objects
	test.my_collection to data/backup/test/my_collection.bson
		 0 objects
	test.foo to data/backup/test/foo.bson
		 6 objects
	test.system.users to data/backup/test/system.users.bson
		 1 objects

mongorestore是Mongodb从备份中恢复数据的工具,它主要用来获取mongodump的输出结果,并将备份的数据插入到运行的Mongodb中。

mongorestore命令使用方法如下:

[root@localhost mongodb]# ./bin/mongorestore --help
usage: ./bin/mongorestore [options] [directory or filename to restore from]
options:
  --help                  produce help message
  -v [ --verbose ]        be more verbose (include multiple times for more
                          verbosity e.g. -vvvvv)
  --version               print the program's version and exit
  -h [ --host ] arg       mongo host to connect to ( <set name>/s1,s2 for sets)
  --port arg              server port. Can also use --host hostname:port
  --ipv6                  enable IPv6 support (disabled by default)
  -u [ --username ] arg   username
  -p [ --password ] arg   password
  --dbpath arg            directly access mongod database files in the given
                          path, instead of connecting to a mongod  server -
                          needs to lock the data directory, so cannot be used
                          if a mongod is currently accessing the same path
  --directoryperdb        if dbpath specified, each db is in a separate
                          directory
  --journal               enable journaling
  -d [ --db ] arg         database to use
  -c [ --collection ] arg collection to use (some commands)
  --objcheck              validate object before inserting
  --filter arg            filter to apply before inserting
  --drop                  drop each collection before import
  --oplogReplay           replay oplog for point-in-time restore
  --keepIndexVersion      don't upgrade indexes to newest version

参数说明:

-h:指明数据库宿主机的IP

-u:指明数据库的用户名

-p:指明数据库的密码

-d:指明数据库的名字

-c:指明collection的名字

-o:指明到要备份的文件名

-q:指明备份数据的过滤条件

 

具体使用示例如下:

[root@localhost mongodb]# ./bin/mongorestore -d test --drop data/backup/test/
connected to: 127.0.0.1
Tue Aug 14 01:18:17 data/backup/test/games.bson
Tue Aug 14 01:18:17 	 going into namespace [test.games]
Tue Aug 14 01:18:17 	 dropping
1 objects found
Tue Aug 14 01:18:17 data/backup/test/foo.bson
Tue Aug 14 01:18:17 	 going into namespace [test.foo]
Tue Aug 14 01:18:17 	 dropping
6 objects found
Tue Aug 14 01:18:17 data/backup/test/blog.post.bson
Tue Aug 14 01:18:17 	 going into namespace [test.blog.post]
Tue Aug 14 01:18:17 	 dropping
1 objects found
Tue Aug 14 01:18:17 data/backup/test/lists.bson
Tue Aug 14 01:18:17 	 going into namespace [test.lists]
Tue Aug 14 01:18:17 	 dropping
1 objects found
Tue Aug 14 01:18:17 data/backup/test/map.bson
Tue Aug 14 01:18:17 	 going into namespace [test.map]
Tue Aug 14 01:18:17 	 dropping
8 objects found
Tue Aug 14 01:18:17 data/backup/test/math.bson
Tue Aug 14 01:18:17 	 going into namespace [test.math]
Tue Aug 14 01:18:17 	 dropping
1 objects found
Tue Aug 14 01:18:17 data/backup/test/system.users.bson
Tue Aug 14 01:18:17 	 going into namespace [test.system.users]
1 objects found
Tue Aug 14 01:18:17 data/backup/test/my_collection.bson
Tue Aug 14 01:18:17 	 going into namespace [test.my_collection]
Tue Aug 14 01:18:17 	 dropping
Tue Aug 14 01:18:17 file data/backup/test/my_collection.bson empty, skipping
Tue Aug 14 01:18:17 data/backup/test/users.bson
Tue Aug 14 01:18:17 	 going into namespace [test.users]
Tue Aug 14 01:18:17 	 dropping
3 objects found
Tue Aug 14 01:18:17 data/backup/test/system.indexes.bson
Tue Aug 14 01:18:17 	 going into namespace [test.system.indexes]
Tue Aug 14 01:18:17 	 dropping
Tue Aug 14 01:18:17 { key: { _id: 1 }, ns: "test.users", name: "_id_" }
Tue Aug 14 01:18:17 { key: { _id: 1 }, ns: "test.games", name: "_id_" }
Tue Aug 14 01:18:17 { key: { _id: 1 }, ns: "test.blog.post", name: "_id_" }
Tue Aug 14 01:18:17 { key: { _id: 1 }, ns: "test.lists", name: "_id_" }
Tue Aug 14 01:18:17 { key: { _id: 1 }, ns: "test.math", name: "_id_" }
Tue Aug 14 01:18:17 { key: { _id: 1 }, ns: "test.map", name: "_id_" }
Tue Aug 14 01:18:17 { key: { gps: "2d" }, ns: "test.map", name: "gps_", min: -180.0, max: 181.0 }
Tue Aug 14 01:18:17 { key: { _id: 1 }, ns: "test.foo", name: "_id_" }
Tue Aug 14 01:18:17 { key: { _id: 1 }, ns: "test.system.users", name: "_id_" }
9 objects found

 

Posted in Uncategorized

Ruby on Rails 4.0 Release Notes

sources:

https://github.com/rails/rails/blob/master/guides/source/4_0_release_notes.md

http://edgeguides.rubyonrails.org/4_0_release_notes.html

Ruby on Rails 4.0 Release Notes

Highlights in Rails 4.0: (WIP)

  • Ruby 1.9.3 only
  • Strong Parameters
  • Queue API
  • Caching Improvements

These release notes cover the major changes, but do not include each bug-fix and changes. If you want to see everything, check out the list of commits in the main Rails repository on GitHub.


Upgrading to Rails 4.0

TODO. This is a WIP guide.

If you’re upgrading an existing application, it’s a great idea to have good test coverage before going in. You should also first upgrade to Rails 3.2 in case you haven’t and make sure your application still runs as expected before attempting an update to Rails 4.0. Then take heed of the following changes:

Rails 4.0 requires at least Ruby 1.9.3

Rails 4.0 requires Ruby 1.9.3 or higher. Support for all of the previous Ruby versions has been dropped officially and you should upgrade as early as possible.

What to update in your apps

  • Update your Gemfile to depend on
    • rails = 4.0.0
    • sass-rails ~> 3.2.3
    • coffee-rails ~> 3.2.1
    • uglifier >= 1.0.3

TODO: Update the versions above.

  • Rails 4.0 removes vendor/plugins completely. You have to replace these plugins by extracting them as gems and adding them in your Gemfile. If you choose not to make them gems, you can move them into, say, lib/my_plugin/* and add an appropriate initializer in config/initializers/my_plugin.rb.

TODO: Configuration changes in environment files

Creating a Rails 4.0 application

<code> You should have the 'rails' rubygem installed $ rails new myapp $ cd myapp </code>

Vendoring Gems

Rails now uses a Gemfile in the application root to determine the gems you require for your application to start. This Gemfile is processed by the Bundler gem, which then installs all your dependencies. It can even install all the dependencies locally to your application so that it doesn’t depend on the system gems.

More information: Bundler homepage

Living on the Edge

Bundler and Gemfile makes freezing your Rails application easy as pie with the new dedicated bundle command. If you want to bundle straight from the Git repository, you can pass the --edge flag:

<code>$ rails new myapp --edge </code>

If you have a local checkout of the Rails repository and want to generate an application using that, you can pass the --dev flag:

<code>$ ruby /path/to/rails/railties/bin/rails new myapp --dev </code>

Major Features

Documentation

  • Guides are rewritten in GitHub Flavored Markdown.

Railties

  • Allow scaffold/model/migration generators to accept a polymorphic modifier for references/belongs_to, for instance
    <code>rails g model Product supplier:references{polymorphic} </code>

    will generate the model with belongs_to :supplier, polymorphic: true association and appropriate migration.

  • Set config.active_record.migration_error to :page_load for development.
  • Add runner to Rails::Railtie as a hook called just after runner starts.
  • Add /rails/info/routes path which displays the same information as rake routes.
  • Improved rake routes output for redirects.
  • Load all environments available in config.paths["config/environments"].
  • Add config.queue_consumer to allow the default consumer to be configurable.
  • Add Rails.queue as an interface with a default implementation that consumes jobs in a separate thread.
  • Remove Rack::SSL in favour of ActionDispatch::SSL.
  • Allow to set class that will be used to run as a console, other than IRB, with Rails.application.config.console=. It’s best to add it to console block.
    # it can be added to config/application.rb
    console do
      # this block is called only when running console,
      # so we can safely require pry here
      require "pry"
      config.console = Pry
    end
  • Add a convenience method hide! to Rails generators to hide the current generator namespace from showing when runningrails generate.
  • Scaffold now uses content_tag_for in index.html.erb.
  • Rails::Plugin is removed. Instead of adding plugins to vendor/plugins, use gems or bundler with path or git dependencies.

Deprecations

Action Mailer

  • Allow to set default Action Mailer options via config.action_mailer.default_options=.
  • Raise an ActionView::MissingTemplate exception when no implicit template could be found.
  • Asynchronously send messages via the Rails Queue.
  • Delivery Options (such as SMTP Settings) can now be set dynamically per mailer action.Delivery options are set via :delivery_method_options key on mail.
    def welcome_mailer(user,company)
      delivery_options = { user_name: company.smtp_user, password: company.smtp_password, address: company.smtp_host }
      mail(to: user.email, subject: "Welcome!", delivery_method_options: delivery_options)
    end

Action Pack

Action Controller

  • Add ActionController::Flash.add_flash_types method to allow people to register their own flash types. e.g.:
    class ApplicationController
      add_flash_types :error, :warning
    end

    If you add the above code, you can use <%= error %> in an erb, and redirect_to /foo, :error => 'message' in a controller.

  • Remove Active Model dependency from Action Pack.
  • Support unicode characters in routes. Route will be automatically escaped, so instead of manually escaping:
    get Rack::Utils.escape('こんにちは') => 'home#index'

    You just have to write the unicode route:

    get 'こんにちは' => 'home#index'
  • Return proper format on exceptions.
  • Extracted redirect logic from ActionController::ForceSSL::ClassMethods.force_ssl intoActionController::ForceSSL#force_ssl_redirect.
  • URL path parameters with invalid encoding now raise ActionController::BadRequest.
  • Malformed query and request parameter hashes now raise ActionController::BadRequest.
  • respond_to and respond_with now raise ActionController::UnknownFormat instead of directly returning head 406. The exception is rescued and converted to 406 in the exception handling middleware.
  • JSONP now uses application/javascript instead of application/json as the MIME type.
  • Session arguments passed to process calls in functional tests are now merged into the existing session, whereas previously they would replace the existing session. This change may break some existing tests if they are asserting the exact contents of the session but should not break existing tests that only assert individual keys.
  • Forms of persisted records use always PATCH (via the _method hack).
  • For resources, both PATCH and PUT are routed to the update action.
  • Don’t ignore force_ssl in development. This is a change of behavior – use an :if condition to recreate the old behavior.
    class AccountsController < ApplicationController
      force_ssl :if => :ssl_configured?
    
      def ssl_configured?
        !Rails.env.development?
      end
    end

Deprecations

  • Deprecated ActionController::Integration in favour of ActionDispatch::Integration.
  • Deprecated ActionController::IntegrationTest in favour of ActionDispatch::IntegrationTest.
  • Deprecated ActionController::PerformanceTest in favour of ActionDispatch::PerformanceTest.
  • Deprecated ActionController::AbstractRequest in favour of ActionDispatch::Request.
  • Deprecated ActionController::Request in favour of ActionDispatch::Request.
  • Deprecated ActionController::AbstractResponse in favour of ActionDispatch::Response.
  • Deprecated ActionController::Response in favour of ActionDispatch::Response.
  • Deprecated ActionController::Routing in favour of ActionDispatch::Routing.

Action Dispatch

  • Add Routing Concerns to declare common routes that can be reused inside others resources and routes.Code before:
    resources :messages do
      resources :comments
    end
    
    resources :posts do
      resources :comments
      resources :images, only: :index
    end

    Code after:

    concern :commentable do
      resources :comments
    end
    
    concern :image_attachable do
      resources :images, only: :index
    end
    
    resources :messages, concerns: :commentable
    
    resources :posts, concerns: [:commentable, :image_attachable]
  • Show routes in exception page while debugging a RoutingError in development.
  • Include mounted_helpers (helpers for accessing mounted engines) in ActionDispatch::IntegrationTest by default.
  • Added ActionDispatch::SSL middleware that when included force all the requests to be under HTTPS protocol.
  • Copy literal route constraints to defaults so that url generation know about them. The copied constraints are :protocol,:subdomain:domain:host and :port.
  • Allows assert_redirected_to to match against a regular expression.
  • Adds a backtrace to the routing error page in development.
  • assert_generatesassert_recognizes, and assert_routing all raise Assertion instead of RoutingError.
  • Allows the route helper root to take a string argument. For example, root 'pages#main' as a shortcut forroot to: 'pages#main'.
  • Adds support for the PATCH verb: Request objects respond to patch?. Routes now have a new patch method, and understand :patch in the existing places where a verb is configured, like :via. Functional tests have a new method patchand integration tests have a new method patch_via_redirect. If :patch is the default verb for updates, edits are tunneled asPATCH rather than as PUT and routing acts accordingly.
  • Integration tests support the OPTIONS method.
  • expires_in accepts a must_revalidate flag. If true, “must-revalidate” is added to the Cache-Control header.
  • Default responder will now always use your overridden block in respond_with to render your response.
  • Turn off verbose mode of rack-cache, we still have X-Rack-Cache to check that info.

Deprecations

Action View

  • Remove Active Model dependency from Action Pack.
  • Allow to use mounted_helpers (helpers for accessing mounted engines) in ActionView::TestCase.
  • Make current object and counter (when it applies) variables accessible when rendering templates with :object or:collection.
  • Allow to lazy load default_form_builder by passing a string instead of a constant.
  • Add index method to FormBuilder class.
  • Adds support for layouts when rendering a partial with a given collection.
  • Remove :disable_with in favor of data-disable-with option from submit_tagbutton_tag and button_to helpers.
  • Remove :mouseover option from image_tag helper.
  • Templates without a handler extension now raises a deprecation warning but still defaults to ERb. In future releases, it will simply return the template content.
  • Add a divider option to grouped_options_for_select to generate a separator optgroup automatically, and deprecate prompt as third argument, in favor of using an options hash.
  • Add time_field and time_field_tag helpers which render an input[type="time"] tag.
  • Removed old text_helper apis for highlightexcerpt and word_wrap.
  • Remove the leading n added by textarea on assert_select.
  • Changed default value for config.action_view.embed_authenticity_token_in_remote_forms to false. This change breaks remote forms that need to work also without JavaScript, so if you need such behavior, you can either set it to true or explicitly pass :authenticity_token => true in form options.
  • Make possible to use a block in button_to helper if button text is hard to fit into the name parameter:
    <%= button_to [:make_happy, @user] do %>
      Make happy <strong><%= @user.name %></strong>
    <% end %>
    # => "<form method="post" action="/users/1/make_happy"n" style="margin: 0px; padding: 0px; border: 0px; ">button_to">
    #      <div>
    #        <button type="submit">
    #          Make happy <strong>Name</strong>
    #        </button>
    #      </div>
    #    </form>"
  • Replace include_seconds boolean argument with :include_seconds => true option in distance_of_time_in_words andtime_ago_in_words signature.
  • Remove button_to_function and link_to_function helpers.
  • truncate now always returns an escaped HTML-safe string. The option :escape can be used as false to not escape the result.
  • truncate now accepts a block to show extra content when the text is truncated.
  • Add week_fieldweek_field_tagmonth_fieldmonth_field_tagdatetime_local_field,datetime_local_field_tagdatetime_field and datetime_field_tag helpers.
  • Add color_field and color_field_tag helpers.
  • Add include_hidden option to select tag. With :include_hidden => false select with multiple attribute doesn’t generate hidden input with blank value.
  • Removed default size option from the text_fieldsearch_fieldtelephone_fieldurl_fieldemail_field helpers.
  • Removed default cols and rows options from the text_area helper.
  • Adds image_urljavascript_urlstylesheet_urlaudio_urlvideo_url, and font_url to assets tag helper. These URL helpers will return the full path to your assets. This is useful when you are going to reference this asset from external host.
  • Allow value_method and text_method arguments from collection_select and options_from_collection_for_select to receive an object that responds to :call such as a proc, to evaluate the option in the current element context. This works the same way with collection_radio_buttons and collection_check_boxes.
  • Add date_field and date_field_tag helpers which render an input[type="date"] tag.
  • Add collection_check_boxes form helper, similar to collection_select:
    collection_check_boxes :post, :author_ids, Author.all, :id, :name
    # Outputs something like:
    <input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" />
    <label for="post_author_ids_1">D. Heinemeier Hansson</label>
    <input id="post_author_ids_2" name="post[author_ids][]" type="checkbox" value="2" />
    <label for="post_author_ids_2">D. Thomas</label>
    <input name="post[author_ids][]" type="hidden" value="" />

    The label/check_box pairs can be customized with a block.

  • Add collection_radio_buttons form helper, similar to collection_select:
    collection_radio_buttons :post, :author_id, Author.all, :id, :name
    # Outputs something like:
    <input id="post_author_id_1" name="post[author_id]" type="radio" value="1" />
    <label for="post_author_id_1">D. Heinemeier Hansson</label>
    <input id="post_author_id_2" name="post[author_id]" type="radio" value="2" />
    <label for="post_author_id_2">D. Thomas</label>

    The label/radio_button pairs can be customized with a block.

  • check_box with an HTML5 attribute :form will now replicate the :form attribute to the hidden field as well.
  • label form helper accepts :for => nil to not generate the attribute.
  • Add :format option to number_to_percentage.
  • Add config.action_view.logger to configure logger for Action View.
  • check_box helper with :disabled => true will generate a disabled hidden field to conform with the HTML convention where disabled fields are not submitted with the form. This is a behavior change, previously the hidden tag had a value of the disabled checkbox.
  • favicon_link_tag helper will now use the favicon in app/assets by default.
  • ActionView::Helpers::TextHelper#highlight now defaults to the HTML5 mark element.

Deprecations

Sprockets

Moved into a separate gem sprockets-rails.

Active Record

  • Add add_reference and remove_reference schema statements. Aliases, add_belongs_to and remove_belongs_to are acceptable. References are reversible.
    # Create a user_id column
    add_reference(:products, :user)
    
    # Create a supplier_id, supplier_type columns and appropriate index
    add_reference(:products, :supplier, polymorphic: true, index: true)
    
    # Remove polymorphic reference
    remove_reference(:products, :supplier, polymorphic: true)
  • Add :default and :null options to column_exists?.
    column_exists?(:testings, :taggable_id, :integer, null: false)
    column_exists?(:testings, :taggable_type, :string, default: 'Photo')
  • ActiveRecord::Relation#inspect now makes it clear that you are dealing with a Relation object rather than an array:
    User.where(:age => 30).inspect
    # => <ActiveRecord::Relation [#<User ...>, #<User ...>]>
    
    User.where(:age => 30).to_a.inspect
    # => [#<User ...>, #<User ...>]

    if more than 10 items are returned by the relation, inspect will only show the first 10 followed by ellipsis.

  • Add :collation and :ctype support to PostgreSQL. These are available for PostgreSQL 8.4 or later.
    development:
      adapter: postgresql
      host: localhost
      database: rails_development
      username: foo
      password: bar
      encoding: UTF8
      collation: ja_JP.UTF8
      ctype: ja_JP.UTF8
  • FinderMethods#exists? now returns false with the false argument.
  • Added support for specifying the precision of a timestamp in the postgresql adapter. So, instead of having to incorrectly specify the precision using the :limit option, you may use :precision, as intended. For example, in a migration:
    def change
      create_table :foobars do |t|
        t.timestamps :precision => 0
      end
    end
  • Allow ActiveRecord::Relation#pluck to accept multiple columns. Returns an array of arrays containing the typecasted values:
    Person.pluck(:id, :name)
    # SELECT people.id, people.name FROM people
    # => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]
  • Improve the derivation of HABTM join table name to take account of nesting. It now takes the table names of the two models, sorts them lexically and then joins them, stripping any common prefix from the second table name. Some examples:
    <code>Top level models (Category &lt;=&gt; Product) Old: categories_products New: categories_products Top level models with a global table_name_prefix (Category &lt;=&gt; Product) Old: site_categories_products New: site_categories_products Nested models in a module without a table_name_prefix method (Admin::Category &lt;=&gt; Admin::Product) Old: categories_products New: categories_products Nested models in a module with a table_name_prefix method (Admin::Category &lt;=&gt; Admin::Product) Old: categories_products New: admin_categories_products Nested models in a parent model (Catalog::Category &lt;=&gt; Catalog::Product) Old: categories_products New: catalog_categories_products Nested models in different parent models (Catalog::Category &lt;=&gt; Content::Page) Old: categories_pages New: catalog_categories_content_pages </code>
  • Move HABTM validity checks to ActiveRecord::Reflection. One side effect of this is to move when the exceptions are raised from the point of declaration to when the association is built. This is consistant with other association validity checks.
  • Added stored_attributes hash which contains the attributes stored using ActiveRecord::Store. This allows you to retrieve the list of attributes you’ve defined.
    class User < ActiveRecord::Base
      store :settings, accessors: [:color, :homepage]
    end
    
    User.stored_attributes[:settings] # [:color, :homepage]
  • PostgreSQL default log level is now ‘warning’, to bypass the noisy notice messages. You can change the log level using themin_messages option available in your config/database.yml.
  • Add uuid datatype support to PostgreSQL adapter.
  • Added ActiveRecord::Migration.check_pending! that raises an error if migrations are pending.
  • Added #destroy! which acts like #destroy but will raise an ActiveRecord::RecordNotDestroyed exception instead of returning false.
  • Allow blocks for count with ActiveRecord::Relation, to work similar as Array#count:Person.where("age > 26").count { |person| person.gender == 'female' }
  • Added support to CollectionAssociation#delete for passing fixnum or string values as record ids. This finds the records responding to the ids and deletes them.
    class Person < ActiveRecord::Base
      has_many :pets
    end
    
    person.pets.delete("1")  # => [#<Pet id: 1>]
    person.pets.delete(2, 3) # => [#<Pet id: 2>, #<Pet id: 3>]
  • It’s not possible anymore to destroy a model marked as read only.
  • Added ability to ActiveRecord::Relation#from to accept other ActiveRecord::Relation objects.
  • Added custom coders support for ActiveRecord::Store. Now you can set your custom coder like this:
    store :settings, accessors: [ :color, :homepage ], coder: JSON
  • mysql and mysql2 connections will set SQL_MODE=STRICT_ALL_TABLES by default to avoid silent data loss. This can be disabled by specifying strict: false in config/database.yml.
  • Added default order to ActiveRecord::Base#first to assure consistent results among different database engines. IntroducedActiveRecord::Base#take as a replacement to the old behavior.
  • Added an :index option to automatically create indexes for references and belongs_to statements in migrations. This can be either a boolean or a hash that is identical to options available to the add_index method:
    create_table :messages do |t|
      t.references :person, :index => true
    end

    Is the same as:

    create_table :messages do |t|
      t.references :person
    end
    add_index :messages, :person_id

    Generators have also been updated to use the new syntax.

  • Added bang methods for mutating ActiveRecord::Relation objects. For example, while foo.where(:bar) will return a new object leaving foo unchanged, foo.where!(:bar) will mutate the foo object.
  • Added #find_by and #find_by! to mirror the functionality provided by dynamic finders in a way that allows dynamic input more easily:
    Post.find_by name: 'Spartacus', rating: 4
    Post.find_by "published_at < ?", 2.weeks.ago
    Post.find_by! name: 'Spartacus'
  • Added ActiveRecord::Base#slice to return a hash of the given methods with their names as keys and returned values as values.
  • Remove IdentityMap – IdentityMap has never graduated to be an “enabled-by-default” feature, due to some inconsistencies with associations, as described in this commit. Hence the removal from the codebase, until such issues are fixed.
  • Added a feature to dump/load internal state of SchemaCache instance because we want to boot more quickly when we have many models.
    # execute rake task.
    RAILS_ENV=production bundle exec rake db:schema:cache:dump
    => generate db/schema_cache.dump
    
    # add config.use_schema_cache_dump = true in config/production.rb. BTW, true is default.
    
    # boot rails.
    RAILS_ENV=production bundle exec rails server
    => use db/schema_cache.dump
    
    # If you remove clear dumped cache, execute rake task.
    RAILS_ENV=production bundle exec rake db:schema:cache:clear
    => remove db/schema_cache.dump
  • Added support for partial indices to PostgreSQL adapter.
  • The add_index method now supports a where option that receives a string with the partial index criteria.
  • Added the ActiveRecord::NullRelation class implementing the null object pattern for the Relation class.
  • Implemented ActiveRecord::Relation#none method which returns a chainable relation with zero records (an instance of theNullRelation class). Any subsequent condition chained to the returned relation will continue generating an empty relation and will not fire any query to the database.
  • Added create_join_table migration helper to create HABTM join tables.
    create_join_table :products, :categories
    # =>
    # create_table :categories_products, :id => false do |td|
    #   td.integer :product_id, :null => false
    #   td.integer :category_id, :null => false
    # end
  • The primary key is always initialized in the @attributes hash to nil (unless another value has been specified).
  • In previous releases, the following would generate a single query with an OUTER JOIN comments, rather than two separate queries:
    Post.includes(:comments).where("comments.name = 'foo'")

    This behaviour relies on matching SQL string, which is an inherently flawed idea unless we write an SQL parser, which we do not wish to do. Therefore, it is now deprecated.

    To avoid deprecation warnings and for future compatibility, you must explicitly state which tables you reference, when using SQL snippets:

    Post.includes(:comments).where("comments.name = 'foo'").references(:comments)

    Note that you do not need to explicitly specify references in the following cases, as they can be automatically inferred:

    Post.where(comments: { name: 'foo' })
    Post.where('comments.name' => 'foo')
    Post.order('comments.name')

    You also do not need to worry about this unless you are doing eager loading. Basically, don’t worry unless you see a deprecation warning or (in future releases) an SQL error due to a missing JOIN.

  • Support for the schema_info table has been dropped. Please switch to schema_migrations.
  • Connections must be closed at the end of a thread. If not, your connection pool can fill and an exception will be raised.
  • Added the ActiveRecord::Model module which can be included in a class as an alternative to inheriting fromActiveRecord::Base:
    class Post
      include ActiveRecord::Model
    end
  • PostgreSQL hstore records can be created.
  • PostgreSQL hstore types are automatically deserialized from the database.
  • Added #update_columns method which updates the attributes from the passed-in hash without calling save, hence skipping validations and callbacks. ActiveRecordError will be raised when called on new objects or when at least one of the attributes is marked as read only.
    post.attributes # => {"id"=>2, "title"=>"My title", "body"=>"My content", "author"=>"Peter"}
    post.update_columns({title: 'New title', author: 'Sebastian'}) # => true
    post.attributes # => {"id"=>2, "title"=>"New title", "body"=>"My content", "author"=>"Sebastian"}

Deprecations

  • Deprecated most of the ‘dynamic finder’ methods. All dynamic methods except for find_by_... and find_by_...! are deprecated. Here’s how you can rewrite the code:
    find_all_by_... can be rewritten using where(...)
    find_last_by_... can be rewritten using where(...).last
    scoped_by_... can be rewritten using where(...)
    find_or_initialize_by_... can be rewritten using where(...).first_or_initialize
    find_or_create_by_... can be rewritten using where(...).first_or_create
    find_or_create_by_...! can be rewritten using where(...).first_or_create!

    The implementation of the deprecated dynamic finders has been moved to the active_record_deprecated_finders gem.

  • Deprecated the old-style hash based finder API. This means that methods which previously accepted “finder options” no longer do. For example this:
    Post.find(:all, :conditions => { :comments_count => 10 }, :limit => 5)

    should be rewritten in the new style which has existed since Rails 3:

    Post.where(comments_count: 10).limit(5)

    Note that as an interim step, it is possible to rewrite the above as:

    Post.scoped(:where => { :comments_count => 10 }, :limit => 5)

    This could save you a lot of work if there is a lot of old-style finder usage in your application.

    Calling Post.scoped(options) is a shortcut for Post.scoped.merge(options)Relation#merge now accepts a hash of options, but they must be identical to the names of the equivalent finder method. These are mostly identical to the old-style finder option names, except in the following cases:

    <code>:conditions becomes :where :include becomes :includes :extend becomes :extending </code>

    The code to implement the deprecated features has been moved out to the active_record_deprecated_finders gem. This gem is a dependency of Active Record in Rails 4.0. It will no longer be a dependency from Rails 4.1, but if your app relies on the deprecated features then you can add it to your own Gemfile. It will be maintained by the Rails core team until Rails 5.0 is released.

  • Deprecate eager-evaluated scopes.Don’t use this:
    scope :red, where(color: 'red')
    default_scope where(color: 'red')

    Use this:

    scope :red, -> { where(color: 'red') }
    default_scope { where(color: 'red') }

    The former has numerous issues. It is a common newbie gotcha to do the following:

    scope :recent, where(published_at: Time.now - 2.weeks)

    Or a more subtle variant:

    scope :recent, -> { where(published_at: Time.now - 2.weeks) }
    scope :recent_red, recent.where(color: 'red')

    Eager scopes are also very complex to implement within Active Record, and there are still bugs. For example, the following does not do what you expect:

    scope :remove_conditions, except(:where)
    where(...).remove_conditions # => still has conditions
  • Added deprecation for the :dependent => :restrict association option.
  • Up until now has_many and has_one, :dependent => :restrict option raised a DeleteRestrictionError at the time of destroying the object. Instead, it will add an error on the model.
  • To fix this warning, make sure your code isn’t relying on a DeleteRestrictionError and then addconfig.active_record.dependent_restrict_raises = false to your application config.
  • New rails application would be generated with the config.active_record.dependent_restrict_raises = false in the application config.
  • The migration generator now creates a join table with (commented) indexes every time the migration name contains the word “join_table”.
  • ActiveRecord::SessionStore is removed from Rails 4.0 and is now a separate gem.

Active Model

  • Changed AM::Serializers::JSON.include_root_in_json default value to false. Now, AM Serializers and AR objects have the same default behaviour.
    class User < ActiveRecord::Base; end
    
    class Person
      include ActiveModel::Model
      include ActiveModel::AttributeMethods
      include ActiveModel::Serializers::JSON
    
      attr_accessor :name, :age
    
      def attributes
        instance_values
      end
    end
    
    user.as_json
    => {"id"=>1, "name"=>"Konata Izumi", "age"=>16, "awesome"=>true}
    # root is not included
    
    person.as_json
    => {"name"=>"Francesco", "age"=>22}
    # root is not included
  • Passing false hash values to validates will no longer enable the corresponding validators.
  • ConfirmationValidator error messages will attach to :#{attribute}_confirmation instead of attribute.
  • Added ActiveModel::Model, a mixin to make Ruby objects work with Action Pack out of the box.
  • ActiveModel::Errors#to_json supports a new parameter :full_messages.
  • Trims down the API by removing valid? and errors.full_messages.

Deprecations

Active Resource

  • Active Resource is removed from Rails 4.0 and is now a separate gem.

Active Support

  • Add default values to all ActiveSupport::NumberHelper methods, to avoid errors with empty locales or missing values.
  • Time#change now works with time values with offsets other than UTC or the local time zone.
  • Add Time#prev_quarter and Time#next_quarter short-hands for months_ago(3) and months_since(3).
  • Remove obsolete and unused require_association method from dependencies.
  • Add :instance_accessor option for config_accessor.
    class User
      include ActiveSupport::Configurable
      config_accessor :allowed_access, instance_accessor: false
    end
    
    User.new.allowed_access = true # => NoMethodError
    User.new.allowed_access        # => NoMethodError
  • ActionView::Helpers::NumberHelper methods have been moved to ActiveSupport::NumberHelper and are now available viaNumeric#to_s.
  • Numeric#to_s now accepts the formatting options :phone, :currency, :percentage, :delimited, :rounded, :human, and :human_size.
  • Add Hash#transform_keysHash#transform_keys!Hash#deep_transform_keys and Hash#deep_transform_keys!.
  • Changed xml type datetime to dateTime (with upper case letter T).
  • Add :instance_accessor option for class_attribute.
  • constantize now looks in the ancestor chain.
  • Add Hash#deep_stringify_keys and Hash#deep_stringify_keys! to convert all keys from a Hash instance into strings.
  • Add Hash#deep_symbolize_keys and Hash#deep_symbolize_keys! to convert all keys from a Hash instance into symbols.
  • Object#try can’t call private methods.
  • AS::Callbacks#run_callbacks remove key argument.
  • deep_dup works more expectedly now and duplicates also values in Hash instances and elements in Array instances.
  • Inflector no longer applies ice -> ouse to words like slice, police.
  • Add ActiveSupport::Deprecations.behavior = :silence to completely ignore Rails runtime deprecations.
  • Make Module#delegate stop using send – can no longer delegate to private methods.
  • AS::Callbacks deprecate :rescuable option.
  • Adds Integer#ordinal to get the ordinal suffix string of an integer.
  • AS::Callbacks :per_key option is no longer supported.
  • AS::Callbacks#define_callbacks add :skip_after_callbacks_if_terminated option.
  • Add html_escape_once to ERB::Util, and delegate escape_once tag helper to it.
  • Remove ActiveSupport::TestCase#pending method, use skip instead.
  • Deletes the compatibility method Module#method_names, use Module#methods from now on (which returns symbols).
  • Deletes the compatibility method Module#instance_method_names, use Module#instance_methods from now on (which returns symbols).
  • Unicode database updated to 6.1.0.
  • Adds encode_big_decimal_as_string option to force JSON serialization of BigDecimals as numeric instead of wrapping them in strings for safety.

Deprecations

  • ActiveSupport::Callbacks: deprecate usage of filter object with #before and #after methods as around callback.
  • BufferedLogger is deprecated. Use ActiveSupport::Logger or the logger from Ruby stdlib.
  • Deprecates the compatibility method Module#local_constant_names and use Module#local_constants instead (which returns symbols).

Credits

See the full list of contributors to Rails for the many people who spent many hours making Rails, the stable and robust framework it is. Kudos to all of them.

Posted in Uncategorized

Rails Active Record Named Scopes

Active Record Named Scopes

Instance Public methods

with_scope(scope = {}, action = :merge, &block) with_scope lets you apply options to inner block incrementally. It takes a hash and the keys must be :find or :create:find parameter is Relation while :create parameters are an attributes hash.

class Article < ActiveRecord::Base
  def self.create_with_scope
    with_scope(:find => where(:blog_id => 1), :create => { :blog_id => 1 }) do
      find(1) # => SELECT * from articles WHERE blog_id = 1 AND id = 1
      a = create(1)
      a.blog_id # => 1
    end
  end
end

In nested scopings, all previous parameters are overwritten by the innermost rule, with the exception of where, includes, and joins operations in Relation, which are merged.

joins operations are uniqued so multiple scopes can join in the same table without table aliasing problems. If you need to join multiple tables, but still want one of the tables to be uniqued, use the array of strings format for your joins.

class Article < ActiveRecord::Base
  def self.find_with_scope
    with_scope(:find => where(:blog_id => 1).limit(1), :create => { :blog_id => 1 }) do
      with_scope(:find => limit(10)) do
        all # => SELECT * from articles WHERE blog_id = 1 LIMIT 10
      end
      with_scope(:find => where(:author_id => 3)) do
        all # => SELECT * from articles WHERE blog_id = 1 AND author_id = 3 LIMIT 1
      end
    end
  end
end

You can ignore any previous scopings by using the with_exclusive_scope method.

class Article < ActiveRecord::Base
  def self.find_with_exclusive_scope
    with_scope(:find => where(:blog_id => 1).limit(1)) do
      with_exclusive_scope(:find => limit(10)) do
        all # => SELECT * from articles LIMIT 10
      end
    end
  end
end

Note: the :find scope also has effect on update and deletion methods, like update_all and delete_all.

default_scope

default_scope(scope = {}) Use this macro in your model to set a default scope for all operations on the model.

class Article < ActiveRecord::Base
  default_scope where(:published => true)
end

Article.all # => SELECT * FROM articles WHERE published = true

The default_scope is also applied while creating/building a record. It is not applied while updating a record.

Article.new.published    # => true
Article.create.published # => true

You can also use default_scope with a block, in order to have it lazily evaluated:

class Article < ActiveRecord::Base
  default_scope { where(:published_at => Time.now - 1.week) }
end

(You can also pass any object which responds to call to the default_scope macro, and it will be called when building the default scope.)

If you use multiple default_scope declarations in your model then they will be merged together:

class Article < ActiveRecord::Base
  default_scope where(:published => true)
  default_scope where(:rating => 'G')
end

Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G'

This is also the case with inheritance and module includes where the parent or module defines a default_scope and the child or including class defines a second one.

If you need to do more complex things with a default scope, you can alternatively define it as a class method:

class Article < ActiveRecord::Base
  def self.default_scope
    # Should return a scope, you can call 'super' here etc.
  end
end

activerecord/lib/active_record/scoping/named.rb

scope(name, scope_options = {}) Adds a class method for retrieving and querying objects. A scope represents a narrowing of a database query, such as where(:color => :red).select('shirts.*').includes(:washing_instructions).

class Shirt < ActiveRecord::Base
  scope :red, where(:color => 'red')
  scope :dry_clean_only, joins(:washing_instructions).where('washing_instructions.dry_clean_only = ?', true)
end

The above calls to scope define class methods Shirt.red and Shirt.dry_clean_onlyShirt.red, in effect, represents the query Shirt.where(:color => 'red').

Note that this is simply ‘syntactic sugar’ for defining an actual class method:

class Shirt < ActiveRecord::Base
  def self.red
    where(:color => 'red')
  end
end

Unlike Shirt.find(...), however, the object returned by Shirt.red is not an Array; it resembles the association object constructed by a has_many declaration. For instance, you can invoke Shirt.red.firstShirt.red.count,Shirt.red.where(:size => 'small'). Also, just as with the association objects, named scopes act like an Array, implementing Enumerable; Shirt.red.each(&block)Shirt.red.first, and Shirt.red.inject(memo, &block) all behave as ifShirt.red really was an Array.

These named scopes are composable. For instance, Shirt.red.dry_clean_only will produce all shirts that are both red and dry clean only. Nested finds and calculations also work with these compositions: Shirt.red.dry_clean_only.count returns the number of garments for which these criteria obtain. Similarly with Shirt.red.dry_clean_only.average(:thread_count).

All scopes are available as class methods on the ActiveRecord::Base descendant upon which the scopes were defined. But they are also available to has_many associations. If,

class Person < ActiveRecord::Base
  has_many :shirts
end

then elton.shirts.red.dry_clean_only will return all of Elton’s red, dry clean only shirts.

Named scopes can also be procedural:

class Shirt < ActiveRecord::Base
  scope :colored, lambda { |color| where(:color => color) }
end

In this example, Shirt.colored('puce') finds all puce shirts.

On Ruby 1.9 you can use the ‘stabby lambda’ syntax:

scope :colored, ->(color) { where(:color => color) }

Note that scopes defined with scope will be evaluated when they are defined, rather than when they are used. For example, the following would be incorrect:

class Post < ActiveRecord::Base
  scope :recent, where('published_at >= ?', Time.current - 1.week)
end

The example above would be ‘frozen’ to the Time.current value when the Post class was defined, and so the resultant SQL query would always be the same. The correct way to do this would be via a lambda, which will re-evaluate the scope each time it is called:

class Post < ActiveRecord::Base
  scope :recent, lambda { where('published_at >= ?', Time.current - 1.week) }
end

Named scopes can also have extensions, just as with has_many declarations:

class Shirt < ActiveRecord::Base
  scope :red, where(:color => 'red') do
    def dom_id
      'red_shirts'
    end
  end
end

Scopes can also be used while creating/building a record.

class Article < ActiveRecord::Base
  scope :published, where(:published => true)
end

Article.published.new.published    # => true
Article.published.create.published # => true

Class methods on your model are automatically available on scopes. Assuming the following setup:

class Article < ActiveRecord::Base
  scope :published, where(:published => true)
  scope :featured, where(:featured => true)

  def self.latest_article
    order('published_at desc').first
  end

  def self.titles
    map(&:title)
  end

end

We are able to call the methods like this:

Article.published.featured.latest_article
Article.featured.titles

scoped(options = nil) Returns an anonymous scope.

posts = Post.scoped
posts.size # Fires "select count(*) from  posts" and returns the count
posts.each {|p| puts p.name } # Fires "select * from posts" and loads post objects

fruits = Fruit.scoped
fruits = fruits.where(:color => 'red') if options[:red_only]
fruits = fruits.limit(10) if limited?

Anonymous scopes tend to be useful when procedurally generating complex queries, where passing intermediate values (scopes) around as first-class objects is convenient.

You can define a scope that applies to all finders using ActiveRecord::Base.default_scope.

Posted in Uncategorized