上一篇:Rails4 升级第一弹: https://ruby-china.org/topics/22280
## uninitialized constant Mongoid::MultiParameterAttributes & Mongoid::Versioning
mongoid4中去掉了MultiParameterAttributes 和Versioning,如果想兼容mongoid3,则需要将3中的对应代码拷贝到4中
copy mongoid-3 to /lib/mongoid/versiong.rb
copy mongoid-3 to /lib/mongoid/multi_parameter_attributes.rb
and add to the requires to initializers/mongoid.rb
require 'mongoid/versioning'
require 'mongoid/multi_parameter_attributes.rb'
```ruby
class CouponMongo
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::MultiParameterAttributes
end
```
https://github.com/mongoid/mongoid/issues/2954
## polymorphic的关联关系在mongoid4中去掉了,官方文档给出的实例如下
So where the following would work before:
```ruby
class Eye
include Mongoid::Document
belongs_to :eyeable, polymorphic: true
end
class Face
include Mongoid::Document
has_one :left_eye, class_name: "Eye", as: :eyeable
has_one :right_eye, class_name: "Eye", as: :eyeable
end
```
This would now need to be modeled as (with the appropriate migration):
```ruby
class Eye
include Mongoid::Document
belongs_to :left_socket, class_name: "Face", inverse_of: :left_eye
belongs_to :right_socket, class_name: "Face", inverse_of: :right_eye
end
class Face
include Mongoid::Document
has_one :left_eye, class_name: "Eye", inverse_of: :left_socket
has_one :right_eye, class_name: "Eye", inverse_of: :right_socket
end
```
mongoid polymorphic扩展:https://ruby-china.org/topics/22508
## mongoid4 update_attributes 去掉了without_protection: true这个参数
Mass assignment security now mirrors Rails 4's behavior. without_protection option was also removed. attr_accessible class method was removed. Mongoid and Strong parameters should work fine for mass assignment protection.
mongoid3
如果对象不存在某属性,则不进行保存,类似与strong_parameter的功能
mongo_class.find_or_initialize_by(id: id).update_attributes(attributes, without_protection: true)
mongoid4则去掉了这一参数,attributes需要进行permit处理
mongo_class.find_or_initialize_by(id: id).update_attributes(attributes)
## set_table_name, set_primary_key.
we should use #table_name = instead of #set_table_name.
otherwise you will get undefined method `set_primary_key' for #<Class:0x37132e0>
```ruby
class CmsClientPid < CmsActiveRecord
- set_table_name "cms_client"
- set_primary_key :pid
+ self.table_name = "cms_client"
+ self.primary_key = 'pid'
end
```
## rails最新版本中,在使用try调用私有方法的时候,有了一些差异
```ruby
class User
include Mongoid::Document
private
def say
puts "hello, world"
end
end
```
rails3:
```ruby
u = User.new
u.try(:say)
==> hello, world
```
rails4:
```ruby
u = User.new
u.try(:say)
==> nil
```
查看详情: https://ruby-china.org/topics/22759
## seo friendly_id
# Gemfile
gem 'friendly_id', '~> 5.0.0'
# edit app/models/user.rb
```ruby
class User < ActiveRecord::Base
extend FriendlyId
friendly_id :name, use: :slugged
end
User.create! name: "Joe Schmoe"
```
# Change User.find to User.friendly.find in your controller
rails3:
User.find(params[:id])
User.find(userid)
User.find("username")
rails4:
User.friendly.find(params[:id])
User.friendly.find(userid)
User.friendly.find("username")
https://github.com/norman/friendly_id/
## transaction
transaction用于回调函数中
rails4中修改transaction_include_action?(action)方法,接收数组,并将方法名改为transaction_include_any_action?(actions)
同时增加::set_transaction_state, :has_transactional_callbacks?两个方法
rails3:
[:transaction, :add_to_transaction, :with_transaction_returning_status, :remember_transaction_record_state, :clear_transaction_record_state, :restore_transaction_record_state, :transaction_record_state,
:transaction_include_action?]
rails4:
[:transaction, :add_to_transaction, :with_transaction_returning_status, :remember_transaction_record_state, :clear_transaction_record_state, :restore_transaction_record_state, :transaction_record_state, :transaction_include_any_action?, :set_transaction_state, :has_transactional_callbacks?]
rails3 接受一个参数, rails4接受一个数组
rails3: transaction_include_action?(action)
rails4: transaction_include_any_action?(actions)
```ruby
rails3:
after_commit :update_profile
def update_profile
do_something if transaction_include_action?(:update)
end
rails4:
after_commit :update_profile
def update_profile
do_something if transaction_include_any_action?([:update])
end
```
## mongoid inc
rails3中inc接收两个参数,rails4则接收一个hash,可以同时增加多个变量的count
rails3:
skill.inc(:users_count, 1)
rails4:
skill.inc(users_count: 1)