是否有可能在 app/lib/model_modifications.rb 中调用之前没有加载 gem,这就是抛出错误的原因??? (我会在底部包含代码)
我有一个旧的应用程序,我已经升级到 rails 3.0(是的,我知道它很旧......这就是我来这里的原因。我必须先把它升级到 3.0,然后才能更高)
我安装了一个 gem,但由于某种未知原因,它没有被应用程序选中。 Rails 控制台找不到方法“validates_existence_of”
gem 是 "gem 'validates_existence', '~> 0.4.0' #rails 3.0 需要 0.4.0"
gem list 输出显示它已安装(在底部)
*** LOCAL GEMS ***
12_hour_time (0.0.4)
abstract (1.0.0)
actionmailer (3.0.1, 2.3.14)
actionpack (3.0.1, 2.3.14)
activemodel (3.0.1)
activerecord (3.0.1, 2.3.14)
activeresource (3.0.1, 2.3.14)
activesupport (3.0.1, 2.3.14)
acts_as_tree (0.1.1)
afm (0.2.2)
arel (1.0.1)
Ascii85 (1.0.3)
barby (0.5.0)
bluecloth (2.2.0)
builder (3.2.4, 2.1.2)
bundler (1.0.22)
coderay (1.1.3)
concurrent-ruby (1.1.8)
debugger-ruby_core_source (1.3.8)
erubis (2.7.0, 2.6.6)
gnuplot (2.6.2, 2.3.6)
hashery (2.1.2)
http-accept (2.1.1)
httpclient (2.8.3)
i18n (0.4.2)
mail (2.7.1, 2.2.20)
mereghost-rails_sql_views (0.8.6)
method_source (1.0.0)
mime-types (1.25.1)
mini_mime (1.1.0)
mini_portile2 (2.5.0)
netrc (0.11.0)
pdf-core (0.0.3)
pdf-reader (1.4.1)
pg (0.11.0)
polyglot (0.3.5)
prawn (0.14.0)
prawn-labels (0.11.3.0)
pry (0.14.1)
racc (1.4.7)
rack (1.2.8, 1.1.6)
rack-mount (0.6.14)
rack-test (0.5.7)
rails (3.0.1, 2.3.14)
rails-upgrade (0.0.2)
rails_sql_views (0.8.0)
railties (3.0.1)
rake (12.2.1, 0.9.2.2)
restful-authentication (1.2.1)
rmagick (2.13.1)
ruby-debug-base19x (0.11.32)
ruby-debug-ide (0.7.2, 0.6.1)
ruby-rc4 (0.1.5)
semver (1.0.1)
soap4r (1.5.8)
soap4r-middleware (0.8.7)
soap4r-ruby1.9 (2.0.5)
sync (0.5.0)
term-ansicolor (1.1.5)
thor (0.14.6)
tins (0.3.14)
treetop (1.6.11, 1.4.15)
ttfunk (1.0.3)
tzinfo (2.0.4, 0.3.60)
validates_existence (0.4.0)
will_paginate (3.0.1, 2.3.15)
但是当我运行 rails 控制台时...我收到此错误
$ rails console
/var/www/rails2314/vendor/soap4r/xsd/iconvcharset.rb:9:in `<top (required)>': iconv will be deprecated in the future, use String#encode instead.
Loading development environment (Rails 3.0.1)
irb(main):001:0> User.first
NoMethodError: undefined method `validates_existence_of' for #<Class:0x00000003ea1278>
from /var/lib/gems/1.9.1/gems/activerecord-3.0.1/lib/active_record/base.rb:1016:in `method_missing'
from /var/www/rails2314/app/lib/model_modifications.rb:50:in `block in included'
from /var/www/rails2314/app/lib/model_modifications.rb:34:in `class_eval'
from /var/www/rails2314/app/lib/model_modifications.rb:34:in `included'
from /var/www/rails2314/app/lib/model_modifications.rb:289:in `include'
from /var/www/rails2314/app/lib/model_modifications.rb:289:in `acts_as_userstamp'
from /var/www/rails2314/app/models/user.rb:2:in `<class:User>'
from /var/www/rails2314/app/models/user.rb:1:in `<top (required)>'
from /var/lib/gems/1.9.1/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:454:in `load'
from /var/lib/gems/1.9.1/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:454:in `block in load_file'
from /var/lib/gems/1.9.1/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:591:in `new_constants_in'
from /var/lib/gems/1.9.1/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:453:in `load_file'
from /var/lib/gems/1.9.1/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:340:in `require_or_load'
from /var/lib/gems/1.9.1/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:491:in `load_missing_constant'
from /var/lib/gems/1.9.1/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:183:in `block in const_missing'
from /var/lib/gems/1.9.1/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:181:in `each'
from /var/lib/gems/1.9.1/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:181:in `const_missing'
from (irb):1
from /var/lib/gems/1.9.1/gems/railties-3.0.1/lib/rails/commands/console.rb:44:in `start'
from /var/lib/gems/1.9.1/gems/railties-3.0.1/lib/rails/commands/console.rb:8:in `start'
from /var/lib/gems/1.9.1/gems/railties-3.0.1/lib/rails/commands.rb:23:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'irb(main):002:0> exit
当我看到 gem 已安装时,我一直在努力弄清楚为什么控制台会说“validates_existence_of”方法丢失了。
它应该在那里,但它不是......我错过了什么?
rails 3.0.1(从 2.3.14 升级)
红宝石 1.9.3p194
为了清楚起见,这里是 lib/model_modification.rb 文件,我认为它造成了很多麻烦。看起来原作者在框架之外做了一些骇人听闻的事情?这造成了一个超级脆弱的局面。
require File.join(File.dirname(__FILE__), "rails_fix.rb")
Rails.logger.debug "MODEL_MODIFICATIONS is called"
class Bignum
def valid_postgres_int?()
return !(self > 2147483647 || self < -2147483648)
end
end
class Fixnum
def valid_postgres_int?()
return true
end
end
class Float
def valid_postgres_int?()
return !(self.to_i > 2147483647 || self.to_i < -2147483648)
end
end
class ProcessorDaemon
def self.add_to(type, tid, source = "fgdb")
return false if Default['civicrm_server'].nil?
tid = tid.to_i.to_s
arr = [File.join(Rails.root, "script", "processor-daemon.sh"), "add", source, type, tid]
# puts arr.inspect
return system(*arr)
end
end
module ActiveRecord
module UserMonitor
def self.included(base)
base.class_eval do
alias_method_chain :create, :user
alias_method_chain :update, :user
class << self
def human_attribute_name_with_cashier_code(f)
if f == 'cashier_code'
return 'PIN'
else
return human_attribute_name_without_cashier_code(f)
end
end
alias_method_chain :human_attribute_name, :cashier_code
end
belongs_to :creator, :foreign_key => "created_by", :class_name => "User"
belongs_to :updator, :foreign_key => "created_by", :class_name => "User"
validates_existence_of :creator, {:allow_nil => true}
validates_existence_of :updator, {:allow_nil => true}
validate :check_cashier
def check_cashier
if self.class.cashierable
if self.class != Contact || current_user.nil? || current_user.contact_id.nil? || current_user.contact_id != self.id
self.errors.add('cashier_code', 'is not valid') if !current_cashier
end
end
end
def current_user
Thread.current['user']
end
def current_cashier
Thread.current['cashier']
end
end
end
def create_with_user
if self.class.record_timestamps
user = current_user
if !user.nil?
self[:created_by] = user.id if respond_to?(:created_by) && created_by.nil?
end
cashier = current_cashier
if respond_to?(:cashier_created_by) && cashier_created_by.nil?
if !cashier.nil? #and self.class.cashierable
self[:cashier_created_by] = cashier.id
else
self[:cashier_created_by] = self[:created_by]
end
end
end
create_without_user
end
def will_not_updated_timestamps!
class << self
def record_timestamps
false
end
end
end
def update_with_user
if self.class.record_timestamps
user = current_user
self[:updated_by] = user.id if respond_to?(:updated_by) and !user.nil?
cashier = current_cashier
if respond_to?(:cashier_updated_by)
if !cashier.nil? and self.class.cashierable # TODO?
self[:cashier_updated_by] = cashier.id
else
self[:cashier_updated_by] = self[:updated_by]
end
end
end
update_without_user
end
def created_by
begin
current_user.class.find(self[:created_by]) if current_user
rescue ActiveRecord::RecordNotFound
nil
end
end
def updated_by
begin
current_user.class.find(self[:updated_by]) if current_user
rescue ActiveRecord::RecordNotFound
nil
end
end
def cashier_created_by
begin
current_user.class.find(self[:cashier_created_by]) if current_user
rescue ActiveRecord::RecordNotFound
nil
end
end
def cashier_updated_by
begin
current_user.class.find(self[:cashier_updated_by]) if current_user
rescue ActiveRecord::RecordNotFound
nil
end
end
end
module MyLogger
def self.included(base)
base.class_eval do
alias_method_chain :update, :log
alias_method_chain :create, :log
alias_method_chain :destroy, :log
end
end
def logaction(action)
return if ! self.class.record_timestamps
if self.class.table_name != "logs" && !self.id.nil? # AND (!["spec_sheets", "builder_tasks"].include?(self.class.table_name)) &&
user = Thread.current['user']
# raise "THIS IS YOUR INFO ... U: #{user.inspect} ... C: #{self.class.inspect} ... S: #{self.inspect}"
cashier = Thread.current['cashier']
l = Log.new
l.table_name = self.class.table_name
l.action = action
l.user_id = user.id if !user.nil?
l.cashier_id = cashier.id if self.class.cashierable && !cashier.nil?
l.cashier_id = l.user_id if l.cashier_id.nil? && !l.user_id.nil?
l.thing_id = self.id
l.date = Time.now
l.save!
end
end
def create_with_log
create_without_log
logaction("create")
end
def destroy_with_log
logaction("destroy")
destroy_without_log
end
def update_with_log
update_without_log
logaction("update")
end
end
end
class Object
def two_places
v = sprintf "%.2f", self
# if v[-1] == "0"[0]
# v = v.chop
# end
v
end
def tp
two_places
end
end
class Struct
def to_hash
h = {}
self.members.each{|x| x = x.to_sym; h[x] = self.send(x)}
return h
end
end
class String
def to_cents
tmp = self.sub(/^\$/, "")
temp = tmp.split('.')
temp[1]=((temp[1]||"0")+"0")[0..1]
temp[0].to_i*100 + temp[1].to_i
end
end
class Fixnum
def to_dollars
"%0d.%02d" % self.divmod(100)
end
end
class OpenStruct
def self.human_name
"Data"
end
def self.human_attribute_name(attr)
attr.humanize
end
end
class ActiveRecord::Base
Rails.logger.debug "ACTIVERECORD BASE is called"
def self.visible_columns
self.all_columns.select{|x| ! self.hidden_columns.include?(x) }
end
def self.custom_option_selects
[]
end
def self.custom_options_for(opt)
return {}[opt]
end
def self.type_override_for(opt)
return {}[opt]
end
def self.editable_columns
self.visible_columns.select{|x| ! self.readonly_columns.include?(x) }
end
def self.all_columns
columns.map{|x| x.name.to_sym}
end
def self.per_page
20
end
def self.hidden_columns
[:lock_version]
end
def self.readonly_columns
[:id, :created_at, :updated_at, :cashier_created_by, :cashier_updated_by, :created_by, :updated_by]
end
def self.associations
retassociations = {}
self.reflect_on_all_associations(:belongs_to).each do |x|
column = x.options[:foreign_key] || x.name.to_s + "_id"
klass = x.options[:class_name] || x.name.to_s.classify
retassociations[column.to_sym] = klass.constantize
end
retassociations
end
def self.distinct(column, conds = [])
self.find(:all, :conditions => conds, :select => "distinct #{column}").map{|x| x.send(column)}
end
def self.acts_as_userstamp
include ActiveRecord::UserMonitor
end
def self.acts_as_logged
include ActiveRecord::MyLogger
end
def self.define_amount_methods_on(method_name)
code = "def #{method_name}
(read_attribute(:#{method_name}_cents)||0).to_dollars
end
def #{method_name}=(value)
if value.kind_of? String
write_attribute(:#{method_name}_cents, value.to_cents)
else
raise TypeError.new(\"Integer math only. Use strings.\")
end
end"
self.module_eval(code)
end
def self.define_amount_methods_on_fake_attr(method_name)
code = "def #{method_name}
((#{method_name}_cents)||0).to_dollars
end
def #{method_name}=(value)
if value.kind_of? String
self.send(:#{method_name}_cents=, value.to_cents)
else
raise TypeError.new(\"Integer math only. Use strings.\")
end
end"
self.module_eval(code)
end
def self.find_all_except(*recs)
return find_all - recs
end
def self.cashierable_possible
cols = self.columns.map{|x| x.name}
cols.include?("cashier_updated_by") || columns.include?("cashier_created_by")
end
def self.allow_shared
false
end
def self.cashierable
return false if !self.cashierable_possible
return true if self.new.current_user && self.new.current_user.shared && !self.allow_shared
return Default[self.class_name.tableize + "_require_cashier_code"] ? true : false
end
def self.prepare_sql(*arr)
a = arr
if a.length == 1 and a.first.class == Array
a = a.first
end
ret = sanitize_sql_for_conditions(a)
return ret
end
def self.execute(*arr)
connection.execute(prepare_sql(*arr))
end
def self.sql(*arr)
prepare_sql(*arr)
end
def add_to_processor_daemon
ProcessorDaemon.add_to(self.class.table_name, self.id)
end
def self.new_or_edit(hash)
obj = nil
if hash[:id] and hash[:id].to_i != 0
obj = self.find(hash[:id].to_i)
hash.delete(:id)
obj.attributes_with_editable = hash
else
obj = self.new
hash.delete(:id)
obj.attributes = hash
end
return obj
end
def editable?
editable = true
if self.respond_to?(:editable)
if ! self.editable
editable = false
end
end
return editable
end
def to_hash(*list)
list = [list].flatten
h = {}
list.each do |k|
h[k] = self.send(k)
end
h
end
def attributes_with_editable=(hash)
should_check = !editable?
before = attributes.clone
retval = (self.attributes=(hash))
after = attributes
if should_check
if before != after
raise
end
end
return retval
end
acts_as_logged
protected
def self.range_math(*ranges)
frange = nil
ranges.each{|a|
pstart, pend = a
pstart = (pstart.hour * 60) + pstart.min
pend = (pend.hour * 60) + pend.min
if frange.nil?
frange = [[pstart, pend]]
else
frange.each{|a2|
fstart, fend = a2
if fstart < pstart and pstart < fend
if pend >= fend
fend = pstart
else
new = [pend, fend]
frange.push(new)
fend = pstart
end
elsif fstart >= pstart and fend <= pend
fstart = fend = nil
elsif pstart <= fstart and pend > fstart
if pend > fend
fstart = fend = nil # shouldn't get here
else
fstart = pend
end
end
a2[0] = fstart
a2[1] = fend
}
frange = frange.select{|x| !(x.first.nil? or x.first == x.last or x.last < x.first)}.sort_by{|x| x.first}
end
}
return frange.map{|y| y.map{|x|
hours = (x / 60).floor
mins = x % 60
Time.parse("#{hours}:#{mins}")
}}
end
end
class Array
def each_with_siblings
self.each_with_index{|b, i|
a = self[i - 1] if i > 0 # -1 does not mean what we want it to
c = self[i + 1]
yield(a, b, c)
}
end
def map_with_index
result = []
self.each_with_index do |elt, idx|
result << yield(elt, idx)
end
result
end
end
# lets call this a hack
# DB.execute("SELECT * FROM defaults;")
class DB < ActiveRecord::Base
def self.exec(*args)
DB.execute(*args)
end
def self.run(*args)
DB.execute(*args)
end
def self.conditions_date_field
return 'created_at'
end
end