Создание данных осветителей для модели с использованием act_as_taggable_on - PullRequest
5 голосов
/ 01 ноября 2010

Я использую плагин acts_as_taggable_on , чтобы обеспечить тегирование для моей Framework модели.У меня есть функциональные тесты, которые генерирует Rails, а также используемые им приборы, и я хотел бы расширить их, добавив некоторые теги, чтобы я мог тестировать поиск по тегам и т. Д.

Нужно ли мнесоздать приборы для таблиц taggings и tag и загрузить их в начало моих функциональных тестов?Если да, то как мне это сделать?Я не разбираюсь в синтаксисе отношений, описанных здесь 1009 *.Будет ли альтернатива захватить экземпляр Framework и добавить к нему теги перед тестированием поведения поиска?Или боги Рельсов поразят меня, если я сделаю это?

Ответы [ 6 ]

7 голосов
/ 22 марта 2015

Я столкнулся с той же проблемой.Я предложил следующий подход после проб и ошибок, прочитал документацию о приспособлениях, ассоциациях и @barnaclebarnes ответ на этот вопрос.

Я сделал это с rails 4.2.0 и действует-как-помечено-включено 3.5.0 .

Примечание: Мой предыдущий ответ сработал, но был немного странным.Я полностью переписал его после того, как @David указал мне более чистый путь - полностью опустил мой метод проб и ошибок и остановился на решении.

Подход, облегчающий большее количество встроенных средств рельсов

Решение @barnaclebarnes обеспечило бы немного больше автоматизма, но также означало бы гораздо больше ввода и учета идентификаторов.Поэтому я продолжал искать более сжатый способ.

Полиморфные отношения

acts_as_taggable_on использует полиморфное отношение с именем taggable для реализации связи между тегами иразные модели.Подробнее о полиморфных отношениях .

Advanced Fixtures

см. Руководство по ActiveRecord :: FixtureSet , описывающее работу ActiveRecord.и что он делает с отношениями приборов (глава Ссылки на метки для ассоциаций ):

Active Record отражает класс модели прибора, находит все ассоциации own_to и позволяет вамукажите целевую метку для ассоциации [...], а не целевой идентификатор для FK [...].

Чуть ниже на странице, есть также некоторые подробности о полиморфностиassign_to.

Это позволило бы определить определение устройства тегирования следующим образом:

tagging:
  taggable: foo (Klass)
  context: tags
  tag: bar

Приборы и модели с пространством имен

ActiveRecord :: TestFixtures обеспечиваетМетод явной установки класса модели для прибора в случае, если он не может быть выведен.Другими словами: вы можете использовать каталоги для фиксации пространства имен и сопоставления их с моделями пространства имен.Чтобы загрузить тестовые данные для тегов и тегов act_as_taggable_on, мы можем поместить их приборы в подпапку fixtures/acts_as_taggable_on/ ( Примечание : fixtures/ActsAsTaggableOn/ также будет работать)

Соберите все вместе

# models/item.rb
class Item < ActiveRecord::Base
  acts_as_taggable_on
end

# fixtures/items.yml
item_1: {}
item_2: {}

# fixtures/acts_as_taggable_on/tags.yml
tag_1:
  name: tag_1
tag_2:
  name: tag_2

# fixtures/acts_as_taggable_on/taggings.yml
tagging_1
  taggable: item_1 (Item)
  context: tags
  tag: tag_1

Если вы добавляете файлы yaml, это позволяет получить довольно низкое определение обслуживания для тегируемых моделей и их экземпляров.

5 голосов
/ 17 августа 2012

Если вы хотите использовать TestUnit, установите несколько тегов (в файле фикстуры tags.yml):

tag_one:
  name: tag one
tag_two:
  name: tag two

И затем установите теги (в файле фикстуры taggings.yml):

tagging_one:
  tag_id: <%= ActiveRecord::Fixtures.identify(:tag_one) %>
  taggable_id: <%= ActiveRecord::Fixtures.identify(:framework_one) %>
  taggable_type: Framework
  context: tags

Обычно ActiveRecord::Fixtures.identify(:tag_one) получает идентификатор для тега, который нужно поместить в правый столбец.

2 голосов
/ 20 ноября 2010

Обычно лучше создавать такие вещи на лету, когда они вам нужны.Светильники могут быстро стать довольно неуправляемыми, и, когда вы посмотрите на тест в будущем, вам нужно будет просмотреть три или четыре файла приспособлений, чтобы выяснить, что происходит.

Я бы порекомендовал уделить немного временипосмотрите на драгоценный камень factory_girl, он сэкономит вам массу времени в будущем.Вы бы сделали что-то вроде этого:

# test/factories.rb
Factory.define :framework do |f|
  # Add any properties to make a valid Framework instance here, i.e. if you have
  # validates_presence_of :name on the Framework model ...
  f.name 'Test Name'
end

Затем в своих функциональных или модульных тестах вы можете легко создавать объекты с определенными свойствами, необходимыми для отдельного теста:

# Create and save in the DB with default values
@framework = Factory.create(:framework)
# Build an object with a different name and don't save it in the DB
@framework = Factory.build(:framework, :name => 'Other name'
# Create with tags
@framework = Factory.build(:framework, :tags_list => 'foo, bar')
1 голос
/ 08 августа 2011

использование: tags_list у меня не сработало:

> undefined method `tags_list=' for #<Project:0xb610b24>

То, что сработало, было на вашем реальном заводе, вам нужно добавить его так:

Factory.define(:project) do |f|
  f.tags_list ("factory")
end

У меня также естьобнаружил, что это должно быть на фабрике родительского уровня, по некоторым причинам это не работает от детей.Я также обнаружил, что вызов

@framework = Factory.build(:framework, :tag_list => 'foo, bar')

не вызывает ошибку, но тихо НЕ создает тег.

Надеюсь, это поможет!

0 голосов
/ 10 декабря 2014

Это самый простой способ добавить теги в ваши тесты. Если у вас есть модель, настроенная так:

class User < ActiveRecord::Base
  acts_as_taggable # Alias for acts_as_taggable_on :tags
  acts_as_taggable_on :skills, :interests
end

И вы используете FactoryGirl, вы можете создать их так:

user1 = create(:user, tag_list: "SomeTag",
                      skill_list: "SomeSkillTag",
                      interest_list: "SomeInterestTag")
0 голосов
/ 15 августа 2013

Вот как я добавляю теги (используя acts-as-taggable-on) к моей модели пользователя (используя factory_girl ):

FactoryGirl.define do 
  factory :post do 
    ...
    trait :poetry do
      after(:create) { |post| post.update_attributes(tag_list: 'poetry') }
    end
  end
end

Таким образом, когда я хочу создать обычный объект Post, я пишу:

create(:post)

но когда я хочу создать Post с тегом poetry, я пишу:

create(:post, :poetry)

И это работает довольно хорошо.

...