代码之家  ›  专栏  ›  技术社区  ›  Michael Giovanni Pumo

Sunspot-如何在JSON输出中包含用户数据?

  •  0
  • Michael Giovanni Pumo  · 技术社区  · 10 年前

    在我的Rails应用程序中,我使用的是Sunspot,这样用户就可以搜索“pin”(如帖子)。所有工作正常,我将数据返回为JSON。

    然而,我还希望在JSON响应中包含与每个“pin”关联的“用户”数据。

    我不需要在搜索中包含“用户”,而只需要在搜索完成后作为每个“pin”的数据。

    我的搜索工作正常,但我无法确定如何添加用户数据。

    module Api
    
        module V1
    
            class PinsController < ApplicationController 
    
                respond_to :json
    
                def index
    
                    _search = Sunspot.search(Pin) do
    
                        fulltext params[:q] do
    
                            highlight :title
                            phrase_fields :title => 2.0
                            phrase_slop 1
                            minimum_match 1
    
                        end
    
                        facet(:position_id, :type_id, :instrument_id, :genre_ids, :skill_id)
    
                        with(:position_id, params[:position]) if params[:position].present?
                        with(:type_id, params[:type]) if params[:type].present?
                        with(:instrument_id, params[:instrument]) if params[:instrument].present?
                        with(:genre_ids).all_of(params[:genre]) if params[:genre].present?
                        with(:skill_id, params[:skill]) if params[:skill].present?
    
                        paginate(:page => params[:page], :per_page => 25)
    
                    end
    
                    _pins = _search.results
    
                    _pins_positions = []
                    _pins_types = []
                    _pins_instruments = []
                    _pins_genres = []
                    _pins_skills = []
    
                    _search.facet(:position_id).rows.each do |row|
                        _facet = Position.find_by_id(row.value)
                        _object = _facet.attributes
                        _object["count"] = row.count
                        _pins_positions << _object
                    end
    
                    _search.facet(:type_id).rows.each do |row|
                        _facet = Type.find_by_id(row.value)
                        _object = _facet.attributes
                        _object["count"] = row.count
                        _pins_types << _object
                    end
    
                    _search.facet(:instrument_id).rows.each do |row|
                        _facet = Instrument.find_by_id(row.value)
                        _object = _facet.attributes
                        _object["count"] = row.count
                        _pins_instruments << _object
                    end
    
                    _search.facet(:genre_ids).rows.each do |row|
                        _facet = Genre.find_by_id(row.value)
                        _object = _facet.attributes
                        _object["count"] = row.count
                        _pins_genres << _object
                    end
    
                    _search.facet(:skill_id).rows.each do |row|
                        _facet = Skill.find_by_id(row.value)
                        _object = _facet.attributes
                        _object["count"] = row.count
                        _pins_skills << _object
                    end
    
                    _pins_positions = _pins_positions.sort_by { |e| e["title"] }
                    _pins_types = _pins_types.sort_by { |e| e["title"] }
                    _pins_instruments = _pins_instruments.sort_by { |e| e["title"] }
                    _pins_genres = _pins_genres.sort_by { |e| e["title"] }
                    _pins_skills = _pins_skills.sort_by { |e| e["title"] }
    
                    _response = {
                        :pins => _pins, 
                        :facets => {
                            :positions => _pins_positions,
                            :types => _pins_types,
                            :instruments => _pins_instruments,
                            :genres => _pins_genres,
                            :skills => _pins_skills
                        }
                    }
    
                    respond_with _response
    
                end
    
            end
    
        end
    
    end
    

    典型的响应如下:

    {"pins":[{
    "id":95,
    "user_id":22,
    "title":"Ratione sint odio vitae in quis aspernatur.",
    "description":"Sunt ut pariatur aut ipsum sit unde alias.",
    "latitude":null,
    "longitude":null,
    "position_id":1,
    "type_id":1,
    "instrument_id":4,
    "skill_id":1,
    "soundcloud_url":null,
    "created_at":"2012-09-04T06:54:17.000Z",
    "updated_at":"2013-10-14T21:58:17.000Z",
    "deleted_at":null
    }],
    "facets":{
    "positions":[{
    "id":1,
    "title":"Non-Professional",
    "token":"non-professional","count":2
    }],
    "types":[{
    "id":1,
    "title":"Wanted",
    "token":"wanted",
    "count":2
    }],
    "instruments":[{
    "id":4,
    "title":"Synth",
    "token":"synth",
    "count":2
    }],
    "genres":[{
    "id":12,
    "title":"Folk",
    "token":"folk",
    "count":2
    },
    {
    "id":16,"title":"Hip Hop","token":"hiphop","count":2}
    ],
    "skills":[{
    "id":3,
    "title":"Advanced",
    "token":"advanced",
    "count":1},
    {
    "id":1,
    "title":"Novice",
    "token":"novice",
    "count":1
    }]
    }}
    

    但是,理想情况下,我希望在JSON中包含每个“pin”的相关“用户”数据。如您所见,我这里只有“user_id”。。。但我希望这个JSON API相当“扁平”,并包含另一个名为“user”的哈希键,该键具有“first_name”、“age”、“gender”等属性。

    如果我使用的是传统的视图模板,我可以将“pin”作为实例变量公开,然后执行以下操作: @pin.user.profile.first_name -在Sunspot中构建数据时,如何做到这一点?

    希望我已经说清楚了。非常感谢!

    1 回复  |  直到 10 年前
        1
  •  0
  •   Michael Giovanni Pumo    10 年前

    我通过创建一个空数组,循环Sunspot的结果,找到相应的用户并推送到数组,找到了一个解决方案。

    _results = _search.results
    _pins = []
    
    _results.each do |pin|
        _object = pin.attributes
        _object["user"] = { :profile => pin.user.profile }
        _pins << _object
    end
    

    我现在得到了一个结构,其中配置文件数据嵌套在pin哈希中的用户密钥中,如下所示:

    enter image description here