代码之家  ›  专栏  ›  技术社区  ›  Edward Dale

使用acts_as_taggable_on为模型创建夹具数据

  •  5
  • Edward Dale  · 技术社区  · 14 年前

    我用的是 acts_as_taggable_on 插件为我的 Framework 模型。我已经得到了Rails生成的功能测试,以及它使用的fixture,我想扩展它们以添加一些标记,这样我就可以测试按标记搜索等等。

    taggings tag 把它们放在我的功能测试的顶部?如果是,我该怎么做?我还没弄清楚描述关系的语法 here 框架 实例并在测试搜索行为之前向其添加标记?或者如果我那样做,上帝会把我击倒吗?

    6 回复  |  直到 14 年前
        1
  •  2
  •   malclocke    14 年前

    一般来说,最好是在你需要的时候随时创造这些东西。fixture可能很快变得很难管理,当您在将来查看测试时,您将需要查看三个或四个fixture文件来取消单击正在发生的事情。

    我建议你花点时间去看看工厂里的女孩宝石,这样你以后就可以省下很多时间了。你会这样做:

    # 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')
    
        2
  •  7
  •   Florian Oberleitner    9 年前

    我也面临同样的问题。在我做了一些尝试和错误之后,我想出了下面的方法,阅读了关于fixture、associations和@barnaclebarnes对这个问题的答案的文档。

    我用的是 .

    备注: 我先前的回答起了作用,但有点古怪。我完全重写了它后,@David指给我一个更干净的方式-完全修改我的试验和错误,并坚持解决方案。

    @巴纳克巴恩斯的解决方案将提供更多的自动化,但也意味着更多的打字和簿记的身份证。所以我一直在寻找更简洁的方法。

    多态关系

    作为可标记的 使用名为 可标记的 实现标签与不同模型之间的关系。有关 polymorphic relations

    高级固定装置

    ActiveRecord::FixtureSet 描述ActiveRecord的工作原理以及它如何处理fixture的关系(第 关联的标签引用

    活动记录反映在设备的模型类上,查找所有属于关联的项,并允许您为关联[…]指定目标标签,而不是为FK[…]指定目标id。

    在页面的下一部分,还提供了多态所属的一些详细信息。

    这将允许这样的标记装置定义:

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

    ActiveRecord::TestFixtures 提供一种方法,用于在无法推断夹具时显式设置该夹具的模型类。 要加载acts_as_taggable_的标记和标记的测试数据,我们可以将它们的fixture放在子文件夹中 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文件打包,这将允许对可标记模型及其实例进行非常低的维护定义。

        3
  •  5
  •   barnaclebarnes    12 年前

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

    然后设置标记(在fixture文件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) 获取要放入右列中的标记的ID。

        4
  •  1
  •   Dan Zinkevich    13 年前

    使用:标记列表对我不起作用:

    > 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')
    

    不会抛出错误,但它不会悄悄地创建标记。

    希望这有帮助!

        5
  •  0
  •   Paweł Gościcki Ywain    11 年前

    这就是我添加标记的方式(使用 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)
    

    但是当我想创造一个 标记为 poetry

    create(:post, :poetry)
    

    而且效果很好。

        6
  •  0
  •   nickwtf    10 年前

    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")