Я пытаюсь соединиться к объектам в единый поток.
Я создал новую модель и контроллер под названием Новостной канал. У меня есть он так, чтобы новостной канал has_many: сообщения и has_many: изображения и изображения и сообщения belong_to: новостной канал. Я настраиваю контроллер прямо сейчас, и я имею:
def index
@messages = Messages.all
@images = Images.all
@feed = ?
end
Как я плавлю их так, это может вытянуть от обоих и поместить их в хронологический порядок, когда каждый требует отдельного форматирования?
Любая справка значительно ценилась бы, спасибо.
Вы можете сделать что-то вроде :
controller:
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
Этот вопрос кажется немного нагруженным, и хотя у меня нет времени на его полное изучение, вот некоторые начальные мысли:
Вы можете объединить два типа элементов, которые вы хотите отобразить, в один массив, а затем отсортировать этот массив на основе поля, которое должно быть общим для двух типов (на ум приходит 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
и у вас должен получиться объединенный массив.
EDIT #2: Если бы я писал это сам, я бы, вероятно, обрабатывал представления примерно так:
на верхнем уровне просто передайте коллекцию фидов в partial, который предназначен для отображения одного элемента:
render :partial => "item", :collection => @feed
это отобразит частицу '_item.html.erb' для каждого элемента в @feed. Кроме того, каждый раз partial будет передавать локальную переменную с именем 'item', которая является элементом @feed для данной конкретной итерации.
сейчас, вероятно, я бы сделал частицу '_item' очень простой, примерно такой:
<%= display_item(item) %>
где display_item - вспомогательный метод вне представления и реализуется с помощью логики типа "is_a?", описанной выше, чтобы выбрать правильный формат отображения для элемента.
Причина, по которой я бы разбил его таким образом, в том, что он использует преимущества некоторых хороших возможностей rails (передача коллекции в partial вместо самостоятельного обращения к коллекции), а затем вынос логики в хелперы (или даже в модели, если это имеет смысл) полезен, потому что упрощает ваши представления. Удержание логики вне представления, когда это возможно, в целом является хорошей практикой, поскольку такую логику трудно тестировать, и ваши представления будет очень трудно читать.
Как насчет
strsplit(gsub("([[:alnum:]]{2})", "\\1 ", x), " ")[[1]]
В основном, добавьте разделитель (здесь «») и затем используйте strsplit
Вероятно, можно было бы сделать лучше, но я сейчас не чувствую себя особенно умным. Это просто чтобы убедиться, что Хаскелл представлен...
Если предположить, что b
уже существует, результат будет помещен в w
.
import List
a l=2*minimum l-maximum l
z=take 3$unfoldr(Just .splitAt 3)b
w=maximum$0:map a(z++transpose z++[map(b!!)[0,4,8],map(b!!)[2,4,6]])
Предполагая, что вход от stdin и выход к stdout,
import List
a l=2*minimum l-maximum l
w b=maximum$0:map a(z++transpose z++[map(b!!)[0,4,8],map(b!!)[2,4,6]])where
z=take 3$unfoldr(Just .splitAt 3)b
main=interact$show.w.read
-121--1152320- Я уверен, что это может быть оптимизировано от гетто-полиморфизма, но это работает на меня, и у меня была идентичная борьба с «как я могу объединить все эти результаты модели?!»
Я использую отдельную модель, как вы, и
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
Двигаясь вперед, я, вероятно, начну упаковывать больше в модель отслеживания потоков, чтобы сэкономить попадания на другие столы, но, надеюсь, вы получите идею.