Подтвердить что ты не робот

Как создать ленту новостей в стиле facebook в рубине на рельсах?

Я пытаюсь подключиться к объектам в один поток.

Я создал новую модель и контроллер под названием Newsfeed. У меня это так, что newsfeed has_many: messages и has_many: изображения и изображения и сообщения принадлежат_to: newsfeed. Я настраиваю контроллер прямо сейчас, и у меня есть:

def index
    @messages = Messages.all
    @images = Images.all
    @feed = ?
end

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

Любая помощь будет принята с благодарностью, спасибо.

4b9b3361

Ответ 1

Вы можете сделать что-то как:

:

def index
    messages = Messages.all
    images = Images.all
    @feed = (messages + images).order_by(&:created_at)
end

view index.html.erb:

<%= render @feed %>

view _feed.html.erb:

<% if feed.is_a? Message %>
  <%= render "message", :locals => {:message => feed}%>
<% else %>
  <%= render "image", :locals => {:image => feed}%>
<% end %>

И добавьте 2 частичных _message.html.erb и _image.html.erb

Ответ 2

Я уверен, что это может быть упрощено из-за этого гетто-полиморфизма, но оно работает для меня, и я столкнулся с одинаковой борьбой с "как мне объединить все эти результаты модели?!"

Я использую отдельную модель, например, вы и наблюдатель:

class NewsfeedObserver < ActiveRecord::Observer

  observe Message, Image

  def after_save(object)
    @item = Newsfeed.create(
              :item_id => object.id, 
              :item_type => object.class.to_s
    )
  end
end

Затем в модели Newsfeed вы можете вытягивать и сортировать по своему усмотрению:

def self.get_items
  item_list = []
  items = find(:all, :order => "created_at DESC", :limit => 30)
  items.collect{ |i| i.item_type.constantize.find(i.item_id) }
end

Затем просто потяните их и покажите в своем представлении, как вам нравится.

#Controller
def index
  @feed = Newsfeed.get_items
end

Двигаясь вперед, я, вероятно, начну собирать больше в модель отслеживания потоков, чтобы сохранять хиты на других таблицах, но, надеюсь, вы получите эту идею.

Ответ 3

Это кажется немного загруженным вопросом, и, хотя у меня нет времени полностью вникать в это, вот несколько начальных мыслей для вас:

  • вы можете объединить два типа элементов, которые хотите отобразить, в один массив, а затем отсортировать этот массив на основе поля, которое должно быть общим между двумя (created_at приходит на ум), чтобы получить их в хронологическом порядке порядок.

  • В представлении вы можете использовать эту единую коллекцию для перебора, а затем использовать хелперы и уникальные частичные части для рендеринга элементов в правильном формате. Это можно сделать, проверив тип объектов, когда вы пытаетесь отобразить его в представлении.

Что-то по строкам:

if item.is_a? Message
  render :partial => 'message', :locals => {:message => item }
elsif item.is_a? Image
  render :partial => 'image', :locals => {:image => item }
end

надеюсь, это поможет некоторым!

EDIT: чтобы объединить массивы, вы можете просто добавить их вместе, используя оператор "+", поскольку массивы в Ruby не должны содержать один тип объекта.

ваши вызовы Messages.all и Images.all дают вам массивы объектов, поэтому просто попробуйте

@messages + @images 

и вы должны иметь объединенный массив.

РЕДАКТИРОВАТЬ № 2: Если бы я сам писал это, я бы, вероятно, обработал взгляды примерно так:

на верхнем уровне, просто передайте свою коллекцию фидов части, которая предназначена для рендеринга одного элемента:

render :partial => "item", :collection => @feed

это приведет к частичной части '_item.html.erb' для каждого элемента в @feed. Кроме того, он будет давать частичную локальную переменную с именем "item" каждый раз, которая является элементом в @feed для этой конкретной итерации.

теперь, я бы, наверное, частичный "_item" был очень простым, например:

<%= display_item(item) %>

где display_item является вспомогательным методом вне представления и реализуется с помощью "is_a?" тип выше, чтобы выбрать правильный формат отображения для элемента.

причина, по которой я сломался, так это то, что она использует некоторые полезные функции рельсов (передайте коллекцию частичной, а не зацикливая на коллекцию), а затем вытащить логику в помощники (или даже модели if это имеет смысл) полезно, потому что это упрощает ваши взгляды. логика из соображений, когда это возможно, является, как правило, хорошей практикой, поскольку такую ​​логику трудно тестировать, и ваши взгляды станут очень трудными для чтения.