我制作了一个小型DRY插件,我想在稍后的某些课程(如剧院,咖啡店,餐厅等)中使用。所有这些类都包含一个地址,因此,我创建了一个带有 act_as_address 方法的地址模型插件,这些方法将被这些类调用,以避免编写重复的代码。
这些类将包含对地址字段的一些验证(如存在和长度),并且我在地址模型中的 act_as_address 中使用了 class_eval 来将这些验证写入课程。但是,它似乎不起作用。
这是我的代码和测试:
# structure.sql
create table addresses (
some_info varchar(25)
# other attrs
);
create table theatres (
id integer,
primary key (id)
) inherits (addresses);
# act_as_address.rb
module Address
module ActsAsAddress
extend ActiveSupport::Concern
include do
end
module ClassMethods
def acts_as_address
class_eval do <<-EVAL
validates :some_info, presence: true
# some other validations, methods etc.
EVAL
end
end
end
end
end
ActiveRecord::Base.send :include, Address::ActsAsAddress
# theatre.rb
class Theatre < ActiveRecord::Base
acts_as_address
end
# address.rb
require 'address/acts_as_address'
module Address
end
# acts_as_address_test.rb
require File.expand_path('../test_helper', __FILE__)
class ActsAsAddressTest < ActiveSupport::TestCase
test "should not be valid" do
assert_not Theatre.create(:some_info => nil).valid?,
"some_info was valid with nil value"
end
end
测试结果如下:
1) Failure:
ActsAsAddressTest#test_should_not_be_valid [acts_as_address_test.rb:16]:
some_info was valid with nil value
有人可以帮我吗?这是 class_eval 的问题吗?我正在使用Ruby on Rails 4。
答案 0 :(得分:2)
您可以这样做:
module Address
module ActsAsAddress
extend ActiveSupport::Concern
module ClassMethods
def acts_as_address
validates :some_info, presence: true
end
end
end
end