2015-07-19 3 views
1

Я сделал небольшой плагин 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.

+0

Почему вам нужен class_eval вообще? Будете ли вы динамически генерировать код? –

+0

Как я уже сказал в своем посте, потому что у меня будет больше таких классов, как Theatre: например Coffeeshop, Restaurant и т. Д. Моя идея - написать act_as_addresses в этих классах, чтобы не было необходимости там проверять адреса (оставаться сухими). – maikovich

+0

ОК, но я до сих пор не думаю, что для этого нужен class_eval. validates - это только метод класса, который уже определен. Вам просто нужно передать правильные аргументы (т. Е. Имя столбца и конкретные проверки). class_eval понадобится только в том случае, если вы хотите определить совершенно новый метод (и даже тогда есть лучшие способы сделать это). –

ответ

2

Вы можете быть в состоянии сделать это:

module Address 
    module ActsAsAddress 
    extend ActiveSupport::Concern 

    module ClassMethods 
     def acts_as_address 
     validates :some_info, presence: true 
     end 
    end 
    end 
end 
Смежные вопросы