ActiveRecord 范围需要一个 Callable 对象。 在 Rails 4 中,所有 ActiveRecord 范围必须使用一个 callable 对象来定义: #Rails 3.2 scope :recent, where(created_at: Time.now - 2.weeks) #Rails 4 scope :recent, -> { where("created_at > ?", Time.now - 2.weeks).order("created_at desc") } scope :active, -> { where(status: 'active') } Activerecord-deprecated-finders 是 Rails 4.0 中默认提供废弃功能的依赖包,但它也将在 4.1 版本中被删除。因此你需要密切关注所有的警告信息,并开始修复这些警告。 Rails 指南 提供一个很有用的解释,关于在大多数情况下如何修改动态查找器: 所有动态的方法除了 findby… 和 findby…! 外都已废弃,你可以使用如下的替代方法: find_all_by_...改为 where(...). find_last_by_...改为 where(...).last. scoped_by_...改为 where(...). find_or_initialize_by_...改为 where(...).first_or_initialize. find_or_create_by_...改为 find_or_create_by(...) 或者 where(...).first_or_create. find_or_create_by_...!改为 find_or_create_by!(...) 或者 where(...).first_or_create!.
#1 Caching with Instance Variables
@current_user ||= User.find(session[:user_id])
#2 Dynamic find_by Methods
@tasks = Task.find(:all, :conditions => ['complete = ?', false]) => @tasks = Task.find_all_by_complete(false) @task = Task.find(:first, :conditions => ['complete =?', false], :order => 'created_at DESC') => @task = Task.find_by_complete(false, :order => 'created_at DESC')
#3 Find Through Association
from @tasks = Task.find(:all, :conditions => ['project_id = ? AND complete = ?', @project.id, false]) to (推荐使用,用association 进行关联) @project = Project.find(params[:id]) @tasks = Task.find(:all, :conditions => ['project_id = ? AND complete = ?', @project.id, false])
#4 Move Find into Model
Move a find into the model to clean up the controllers and remove duplication. 将 find 转移到model中,清洁controllers from class TaskController < ApplicationController def index @tasks = Task.find_all_by_complete(:false, :order => "created_at DESC") end end to class Task < ActiveRecord::Base belongs_to :project def self.find_incomplete find_all_by_complete(:false, :order => "created_at DESC") end end
#5 Using with_scope
class Task < ActiveRecord::Base belongs_to :project def self.find_incomplete(options = {}) with_scope :find => options do find_all_by_complete(false, :order => 'created_at DESC') end end end @tasks = @project.tasks.find_incomplete :limit => 20
#6 Shortcut Blocks with Symbol to_proc
projects.collect { |p| p.name } => ["Write another ASCIIcast", "Go out walking"] projects.collect {&:name} => ["Write another ASCIIcast", "Go out walking"] projects.collect(&:name).collect(&:upcase) => ["WRITE ANOTHER ASCIICAST", "GO OUT WALKING"] projects.each {|project| project.save!} == projects.each(&:save!)
#16: Virtual Attributes (revised)
简介:对原生的attributes(collums),进行逻辑封装 schema.rb create_table "products", :force => true do |t| t.string "name" t.integer "price_in_cents" t.datetime "released_at" ... ... end 1、转换 {price_in_cents => price_in_dollars} <%= f.label :price_in_dollars %> <%= f.text_field :price_in_dollars %> attr_accessible :name, :price_in_dollars def price_in_dollars price_in_cents.to_d/100 if price_in_cents end def price_in_dollars=(dollars) self.price_in_cents = dollars.to_d*100 if dollars.present? end 2、对 released_at 进行逻辑封装 {release_at => relese_at_text} attr_writer :released_at_text validate :check_released_at_text before_save :save_released_at_text def released_at_text @released_at_text || released_at.try(:strftime, "%Y-%m-%d %H:%M:%S") end def save_released_at_text self.released_at = Time.zone.parse(@released_at_text) if @released_at_text.present? end def check_released_at_text if @released_at_text.present? && Time.zone.parse(@released_at_text).nil? errors.add :released_at_text, "cannot be parsed" end rescue ArgumentError errors.add :released_at_text, "is out of range" end 3、支持创建新的 category <%= f.label :category_id %>
<%= f.collection_select :category_id, Category.order(:name), :id, :name %> or create one:<%= f.text_field :new_category %> attr_accessible :new_category attr_accessor :new_category before_save :create_category #在保存 product 前,先前所依赖的 category创建出来 def create_category self.category = Category.create!(name: new_category) if new_category.present? end
#17、habtm-checkboxs
典型的多对多的关系 ,且使用关联表Categorization class Product < ActiveRecord::Base has_many :categorizations has_many :categories, through: :categorizations end class Categorization < ActiveRecord::Base belongs_to :category belongs_to :product end class Category < ActiveRecord::Base has_many :categorizations has_many :products, through: :categorizations end rails consle分析 p=produc.first => select "products".* from "products" limit 1 p.category_ids => select categories.id from categories inner join categorizations on categories.id=categorization.category_id where categorizations.product_id=1 p.category_ids=[1,2] => 1、select * from categories where id IN (1,2) 2、select * from categories inner join categorizations on categoris.category_id=categorization.category_id where categorizations.product_id=1 3、insert into categorizations ... values category_id=1,product_id=1 4、insert into categorizations ... values category_id=2,product_id=1 p.categories =>[#,# ] _form.html.erb <%= hidden_field_tag "product[category_ids][]", nil %> <% Category.all.each do |category| %> <%= check_box_tag "product[category_ids][]", category.id, @product.category_ids.include?(category.id), id: dom_id(category) %> <%= label_tag dom_id(category), category.name %> <% end %>