如何创建ActionController以获取带有标记列表的项目

时间:2016-05-14 07:46:44

标签: ruby-on-rails actioncontroller

数据库表,第一个表包含标签(id,name),第二个表包含项和标签之间的关系。

  tags        
       id   name     
        1   TagA   
        2   TagB   
        3   TagC


 tags_items     
       item_id    tag_id
          1          1
          1          2
          1          3
          2          1
          2          3

活跃的reocrds:

  class Tag < ActiveRecord::Base
      has_many :tags_itemses

      validates_presence_of :name
      validates_length_of :name,  :maximum => 15
    end

    class TagsItems < ActiveRecord::Base
      has_many :tags
    end

在我的控制器中我有索引方法:

def index
        items = TagItems.all.includes(:tags)
        render json: items,
               status: 200
      end

控制器应如何跟随json?

    [{item_id :1, tags: [{id:1, name: TagA}, {id:2, name: TagB}, {id:3, name: TagC}]},
     {item_id :2, tags: [{id:1, name: TagA}, {id:3, name: TagC}]}]

1 个答案:

答案 0 :(得分:1)

您可以使用include选项自定义JSON输出:

class TagsController
  def index
    items = TagItems.all.includes(:tags)
    render json: items, includes: {
       tags: {
         only: [:id, :name]
       }
     }, status: 200
  end
end

但是这可能会变得非常重复,并让控制器膨胀 - active_model_serializers可以在这里提供帮助。

然而这仍然无效,因为您的建模已经过时了!模型名称应该始终是单数! tags_items如果是has_and_belongs_to_many关系则是合适的,但这是一个非常特殊的情况,因为这是一个没有关联模型的连接表。

gollum grammar

您想要的是使用has_many :through关系在标签和项目之间设置多对多:

class Item < ActiveRecord::Base
  has_many :tag_items # you're not Gollum!
  has_many :tags, through: :tag_items
end

class Tag < ActiveRecord::Base
  has_many :tag_items
  has_many :items, through: :tag_items
end

class TagItem < ActiveRecord::Base
  belongs_to :tag
  belongs_to :item
end

您还需要更正表格的名称!使用rails g migration RenameTagsItems创建迁移并修改内容:

class RenameTagsItemsMigration < ActiveRecord::Migration
  def change
    rename_table :tags_items, :tag_items
  end
end

然后运行迁移(rake db:migrate)。