Skip to content

Instantly share code, notes, and snippets.

@Adrian2112
Created May 11, 2015 22:51
Show Gist options
  • Save Adrian2112/9c7378cc2c77665ebea0 to your computer and use it in GitHub Desktop.
Save Adrian2112/9c7378cc2c77665ebea0 to your computer and use it in GitHub Desktop.
Rails 4 updates

http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-from-rails-3-2-to-rails-4-0

commits marked with [rails 4]

##no more match routes # change match 'logout' => 'user_sessions#destroy', :as => :logout

# to
post 'logout' => 'user_sessions#destroy', :as => :logout

if different http verbs needed this can be set with the as: option

match 'logout' => 'user_sessions#destroy', :as => :logout, via: [:get, :post]

##Change scopes to use lambdas # change scope :training, where(:name => "Training User")

# to
scope :training, -> { where(:name => "Training User") }

conditions in query changed to where. Same in model scopes

# change
@user = User.find(:first, :conditions => ["lower(email) = ?", @email])

# to
@user = User.where("lower(email) = ?", @email).first
  • #change has_many :loop_component_notification_responses, :through => :notification, :conditions => { :override_id => nil }

    to

    has_many :loop_component_notification_responses, -> { where(override_id: nil) }, through: :notification

##change serialized columns to pg json columns. # removed serialize :preferences, JSON

# change column
change_column :accounts, :preferences, :json, default: {}

json columns cannot be changed as hash[:key] = value ActiveModel does not detect that the hash has changed. If changed this way mark object as will be changed

class CannedMessageMatrix
  def remove_canned_message(message_id)
		...
    	self.matrix_will_change!

	    self.matrix.each do |k,v|
   		   v.delete(message_id)
	      self.matrix[k] = v
   		 end
	end
	
	...
end

or change the whole hash object

hash = object.hash.clone
hash[:a] = 1
object.hash = hash

##dynamic find methods deprecated except find_ by_ ...

# change
token = TrainingToken.find_or_create_by_email_and_practice_id(row[:email_address], practice.id)

#to
token = TrainingToken.find_or_create_by(email: row[:email_address], practice_id:  practice.id)
  • change

    matrix = klass.find_or_initialize_by_account_id_and_practice_id(current_account.id, current_account.practice.id)

    to

    matrix = klass.find_or_initialize_by(account_id: current_account.id, practice_id: current_account.practice.id)

ActiveRecord #all returns a scope

we had this and I was getting a NoMethodError: undefined method 'delete_at' for ActiveRecord_Relation ...

entities = self.order(:name)
...
other = entities.delete_at(other_idx)

User.all.delete_at(1)
# NoMethodError: undefined method `delete_at' for #<User::ActiveRecord_Relation:0x007fe5c67e2b48>

entities = self.order(:name).to_a # to actually execute the query and get an array
other = entities.delete_at(other_idx)

##strong parameters

gem 'protected_attributes'

I added this gem for backward compatibility so we can keep using attr_accessible :account_id, :acknoweldged_at, :content, …

Rails 4 now uses strong parameters. Lets try to change code to this method so on refactoring we know which parameters are needed for an specific action

params = ActionController::Parameters.new({a: 1, b: 2, c: 3})
params.permit(:a)
# => {"a"=>1}

when a parameter is required use #require

params.require(:d)
# => ActionController::ParameterMissing: param is missing or the value is empty: d

require returns the value of the required attributes

params = ActionController::Parameters.new({user: {name: 'Adrian', number: 12}})
params.require(:user)
=> {"name"=>"Adrian", "number"=>12}
params.require(:user).permitted?
=> true

we need the parameters to return true on #permitted?

params = ActionController::Parameters.new({ user: {username: "john"}})
User.new(params[:user])
# => ActiveModel::ForbiddenAttributesError

User.new(params.require(:user))

example.

class UserController
	def create
		User.create(user_params)
	end
	
	private
	
	def user_params
		params.require(:user).permit(:username, :other, :other2, ...)
	end
end

more here http://blog.trackets.com/2013/08/17/strong-parameters-by-example.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment