Я сделал небольшой плагин DRY, который я хочу использовать в некоторых своих классах (например, театр, кофейня, ресторан и т. Д.) Позже. Все эти классы состоят из адреса, и поэтому я создал модуль модели Address с методом act_as_address, который должен быть вызван этими классами, чтобы избежать дублирования кода.Плагин Ruby on Rails - добавление проверки в класс не работает должным образом
Классов будут состоять из некоторых валидаций на полях адреса (например, наличие и длину), и я использовал class_eval внутри act_as_address в модели Адреса для написания этих заверений классов. Однако, похоже, это не работает.
Вот мой код и тесты:
# 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.
Почему вам нужен class_eval вообще? Будете ли вы динамически генерировать код? –
Как я уже сказал в своем посте, потому что у меня будет больше таких классов, как Theatre: например Coffeeshop, Restaurant и т. Д. Моя идея - написать act_as_addresses в этих классах, чтобы не было необходимости там проверять адреса (оставаться сухими). – maikovich
ОК, но я до сих пор не думаю, что для этого нужен class_eval. validates - это только метод класса, который уже определен. Вам просто нужно передать правильные аргументы (т. Е. Имя столбца и конкретные проверки). class_eval понадобится только в том случае, если вы хотите определить совершенно новый метод (и даже тогда есть лучшие способы сделать это). –