Remove a specific ActiveRecord error message from a models errors collection
Example (where user is an instance variable of my User model):
Blog of hacker, inventor, and serial entrepreneur Noel Geren. Software/hardware, we don't discriminate. How-to's and how-not's.
Example (where user is an instance variable of my User model):
I recently needed to pull down monthly search totals for a number of keywords, after a quick search, that came up empty, I decided to whip one out and post the code (simplified of course), which uses the Google Ads API, Ruby and the Ruby Google Ads API client library (http://code.google.com/p/google-api-ads-ruby/). In order to run this example, you must first initialize your sandbox accounts, described in my previous posting, as well as have ruby and the Ads API libraries installed.
The following snippet initializes new accounts for the specified google account, within the Adwords SANDBOX , using the Adwords4r gem. Replace "your-user-name" with your google accounts user name. Happy Adwords'n.
I needed a quick test script that I could fire up easily on almost any machine to validate the differences I was seeing in Bing results across their cluster as well as investigate their geo-targeted and facebook integrated results, so I whipped up this handy PHP script for scraping SERP rankings. Instead of filing it away in my massive archive of utility scripts, I thought I'd release it.
Simple Ruby ActiveModel class that works with View and Form helpers in Rails 3. Appears to handle dates properly. Let me know if any problems arise:
class CreditCard
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name
attr_accessor :number
attr_accessor :expiration_date
attr_accessor :code
validates_presence_of [ :name, :number, :expiration_date, :validation_code ]
validates_format_of :number, :with => /^\d+$/, :if => Proc.new {|o| !o.card_number.blank? && !o.errors[:card_number] }
validates_format_of :code, :with => /^\d+$/, :if => Proc.new {|o| !o.code.blank? && !o.errors[:code] }
def initialize( attrs = {} )
if !attrs.nil? then
dattrs = {}
attrs.each do |n, v|
if n.match( /^(.+)\(.+\)$/ ) then
an = Regexp.last_match[1]
dattrs[an] = [] if dattrs[an].nil?
dattrs[an] << { :n => n, :v => v }
else
send( "#{n}=", v)
end
end
dattrs.each do |k, v|
vs = v.sort_by{|hv| hv[:n] }.collect{|hv| hv[:v] }
p1 = vs[0]
p2 = ( vs[1].size() > 0 ? ( vs[1].size() == 1 ? "0#{vs[1]}" : vs[1] ) : "01" )
p3 = ( vs[2].size() > 0 ? ( vs[2].size() == 1 ? "0#{vs[2]}" : vs[2] ) : "01" )
dv = [ p1, p2, p3 ].join( "-" )
begin send( "#{k}=", Date.parse( dv ) ); rescue; end
end
end
end
def persisted?
false
end
end
require 'net/http'
debug = Proc.new{|msg| STDERR.puts "[#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}] #{msg}" }
page = nil
http = Net::HTTP.new( "www.google.com", 80 )
req = Net::HTTP::Get.new( "/search?num=20&hl=en&noj=1&q=test&btnG=Search", { "Accept-Encoding" => "gzip", "User-Agent" => "gzip" } )
debug.call( "Performing HTTP GET request for (#{req.path})." )
res = http.request( req )
debug.call( "Received HTTP Response Code (#{res.code})" )
case res
when Net::HTTPSuccess then
begin
if res.header[ 'Content-Encoding' ].eql?( 'gzip' ) then
debug.call( "Performing gzip decompression for response body." )
sio = StringIO.new( res.body )
gz = Zlib::GzipReader.new( sio )
page = gz.read()
debug.call( "Finished decompressing gzipped response body." )
else
debug.call( "Page is not compressed. Using text response body. " )
page = res.body
end
rescue Exception
debug.call( "Error occurred (#{$!.message})" )
# handle errors
raise $!.message
end
end
puts page
I recently ran into a situation where proper table normalization in my design left me with a clunky UI implementation, and no change logging. I also needed a way to directly access underlying (has-one) records for an object, through it's own accessor (think batch import). In the past, for chang logging, I've used ActiveRecord observers, or used an existing library such as Paper Trail, but I wanted this to fit into my scoped non-library dependent design and allow easy access to the underlying has-one records.
class User < ActiveRecord::Base
default_scope :conditions => { :deleted_at => nil }
has_many :phones
validates_presence_of [ :first_name, :last_name, :cell_phone ]
validates_format_of :cell_phone, :with => /\d{3}-\d{3}-\d{4}/, :if => Proc.new {|o| !o.errors.on( :cell_phone ) }
accepts_nested_attributes_for :phones
def cell_phone
@cell_phone || ( !self.phones.empty? ? self.phones.cell.first.number : nil )
end
def cell_phone=( value )
@cell_phone = value
if self.phones.cell.empty? then
self.phones.build( :phone_type => 'cell', :number => value )
else
phone = self.phones.cell.first
self.phones_attributes = [ { :id => phone.id, :number => value } ]
end
end
def destroy
self.update_attribute( :deleted_at, Time.now )
end
end
class Phone < ActiveRecord::Base
default_scope :conditions => { :deleted_at => nil }
named_scope :cell, :conditions => { :phone_type => 'cell' }
belongs_to :user
def destroy
self.update_attribute( :deleted_at, Time.now )
end
end
Stumbled across the same MySQL Gem error (uninitialized constant MysqlCompat::MysqlRes) that I ran into recently on OSX/Snow Leopard when upgrading/building the MySQL 2.8.11 Gem against MySQL 5.5 client libraries on Linux.
ActiveMerchant::Billing::AuthorizeNetCimGateway "create_customer_profile" and "update_customer_payment_profile" method does not support the "validation_mode" option, which tells Authorize.net how to perform validations against the optionally provided payment profile(s) (See bottom of page 14 of CIM XML implementation guide - "validationMode"). The patch below implements the support for the missing option in both methods.
module ActiveMerchant
module Billing
class AuthorizeNetCimGateway < Gateway
alias :original_build_create_customer_profile_request :build_create_customer_profile_request
def build_create_customer_profile_request(xml, options)
add_profile( xml, options[:profile] )
xml.tag!( 'validationMode', CIM_VALIDATION_MODES[ options[:validation_mode] ] ) if options[:validation_mode]
xml.target!
end
alias :original_build_update_customer_payment_profile_request :build_update_customer_payment_profile_request
def build_update_customer_payment_profile_request(xml, options)
xml.tag!('customerProfileId', options[:customer_profile_id])
xml.tag!('paymentProfile') do
add_payment_profile(xml, options[:payment_profile])
end
xml.tag!( 'validationMode', CIM_VALIDATION_MODES[ options[:validation_mode] ] ) if options[:validation_mode]
xml.target!
end
end
end
end
I've seen many postings regarding issues with running 64bit Ruby, Rails and MySQL 5.5 in Leopard/Snow Leopard, especially regarding the missing const error "MysqlCompat::MysqlRes" and the mysql.bundle library issues. After investing about an hour, I had an upgraded MySQL 5.5 and MySQL gem 2.8.1 installation, and I did it like this ...