Rails - Создание собственного JSON с использованием JBuilder

В настоящее время я работаю над личным проектом на Rails 4, и в одном из контроллеров у меня есть массив из трех разных объектов, которые я пытаюсь преобразовать в JSON. Я использую find_by_sql метод для запроса БД с пользовательским запросом MySQL. Код выглядит следующим образом:

Контроллер:

class ActivitiesController < ApplicationController
  def index
    user = current_user.id # using devise
    limit = 100

    likes = Like.find_by_sql(...)
    shares = Share.find_by_sql(...)
    comments = Comment.find_by_sql(...)

    @activities = [likes, shares, comments]
  end
end

Каждый из трех объектов содержит разные поля. Например, likes Объект содержит поля, такие как post_id, first_name, last_name и т. д. shares объект содержит поля, такие как post_id, share_count, shared_time и т. д.

Это JSON, который я хочу вывести:

{
    "likes": [
      { "post_id": "7", "first_name": "Yss", "last_name": "Salas", "profile_pic": "345943754_o.png" },
      { "post_id": "34", "first_name": "Jessica", "last_name": "Nigri", "profile_pic": "pikachu.png" }
    ],
    "shares": [
      { "post_id": "43", "share_count": 54, "shared_time": "2014-05-04 15:14:45" },
      { "post_id": "54", "share_count": 17, "shared_time": "2014-05-24 03:43:45" }
    ],
    "comments": [
      { "post_id": "34", "first_name": "Yss", "last_name": "Salas", "comment": "¡Me gustas mucho!" },
      { "post_id": "12", "first_name": "Jenna", "last_name": "Marbles", "comment": "Blah blah blah look at my ugly dog awwwww!" }
    ]
}

Index.json.jbuilder:

json.array! @activities do |subactivities|
  json.array! subactivities do |activity|
    if activity.class == Like
      json.likes.post_id activity.post_id #exception raised in this line
      json.likes.title activity.title
      json.likes.first_name activity.first_name
      json.likes.last_name activity.last_name
      json.likes.profile_pic activity.profile_pic
    elsif activity.class == Share
      json.shares.post_id activity.post_id
      json.shares.share_count activity.share_count
      json.shares.shared_time activity.shared_time
    else
      json.comments.post_id activity.post_id
      json.comments.first_name activity.first_name
      json.comments.last_name activity.last_name
      json.comments.comment activity.comment
    end
  end
end

Вышесказанное вызывает исключение NoMethodError in Activities#index, undefined method 'post_id' for #<Object:0x00000003064250>, Я очень новичок в Rails, и я предполагаю, что это происходит, потому что нет json.likes свойство присваивать значения. Как я могу построить вышеупомянутую структуру JSON с JBuilder?

2 ответа

Решение

Со страницы Jbuilder на GitHub решение довольно простое. Все, что нужно сделать, это передать переменные экземпляра в блок и вручную назначить пары ключ / значение.

В приведенном ниже примере будет создан массив пар ключ / значение для @likes переменная экземпляра:

# activities/index.json.jbuilder

json.likes @likes do |like|
  json.post_id like.post_id
  json.first_name like.user.first_name
  json.last_name like.user.last_name
  json.profile_pic like.user.profile_pic
end

Выше будет выводить:

{
  "likes": [
    { "post_id": 7, "first_name": "Yss", "last_name": "Salas", "profile_pic": "345943754_o.png" },
    { "post_id": 34, "first_name": "Jessica", "last_name": "Nigri", "profile_pic": "pikachu.png" }
  ],
}

Вы можете сделать это без JBuilder, проще и быстрее.

def index
  user = current_user.id # using devise
  limit = 100

  likes = Like.find_by_sql(...).map(&:attributes) # this will return an array of JSON objects
  shares = Share.find_by_sql(...).map(&:attributes)
  comments = Comment.find_by_sql(...).map(&:attributes)

  @activities = {"likes" => likes, "shares" => shares, "comments" => comments}
end

Таким образом, у вас есть хэш со всей необходимой информацией. Также может быть лучше извлечь логику поиска лайков, публикаций и комментариев в отдельный класс, чтобы вы могли позвонить InformationCollector.collect и это даст вам ответ, который вам нужен.

Другие вопросы по тегам