Как Вы заставляете метод относиться к набору объектов ActiveRecord

Вы ищете итерации по декартовому произведению.

Вот способ перебрать декартову.

from itertools import product
import numpy as np

L1=np.linspace(1, 2, 2)
M5=np.linspace(16, 17, 2)
dconf = dict(data=5)
size = L1.size
loop_size = size**2

def propagate(N, data, modifiers):
    data.update(modifiers)
    out = []
    for i in range(N):
        out.append('%s : %s : %s : %s'%(i, *data.values()))
    return out

mod = (dict(L1=i, M5=j) for i, j in product(L1, M5))
m = map(propagate, np.arange(2, 2+loop_size), (dconf,)*loop_size, mod)

for outer in m:
    for inner in outer:
        print(inner)

Это вы можете адаптировать к своему коду, и если вам действительно нужно идти параллельно (со всем, что это означает с точки зрения разделения информации между ядрами), возможно, посмотрите на Dask.

Надеюсь, этого достаточно, чтобы вы пошли.

Редактировать: ваш вопрос довольно сложно определить. Ваш вопрос действительно, как просто выполнить простой «вызов функции»? Полагаю, один из ответов - просто создать функцию обтекания, что-то вроде ...

def propagate(N, data, modifiers):
    ...

def call_propagate(N, data, L1_, M5_):
    mod = ...
    m = map(...
    return m

for outer in call_propagate(1000, dconf, L1, M5)
    for inner in outer:
        print(inner)
9
задан 22 October 2008 в 00:59
поделиться

6 ответов

Следующее назовет to_csv на всех экземплярах включенным в массив сообщений.

messages = Message.find(:all)
csv = messages.map { |message| message.to_csv }

В направляющих, в Ruby 1.9 или с Symbol#to_proc, доступным через другие средства, можно также сократить его к:

csv = messages.map(&:to_csv)

Более длинная форма полезна, когда Вы хотите сделать более сложную операцию:

csv = messages.map { |message| 
  if message.length < 1000
    message.to_csv
  else
    "Too long"
  end
}
6
ответ дан 4 December 2019 в 20:26
поделиться

Поместите это в файл в lib/. Я рекомендовал бы назвать его чем-то как base_ext.rb

require 'fastercsv'
class ActiveRecord::Base
  def self.to_csv(objects, skip_attributes=[])
    FasterCSV.generate do |csv|
      csv << attribute_names - skip_attributes
      objects.each do |object|
        csv << (attribute_names - skip_attributes).map { |a| "'#{object.attributes[a]}'" }.join(", ")
      end
    end
  end
end

После этого перейдите к config/environment.rb и поместите require 'base_ext' у основания файла для включения нового расширения. После перезапуска Вашего сервера у Вас должен быть доступ к a to_csv метод на всех образцовых классах и когда Вы передаете его массив объектов, должен генерировать хороший формат CSV для Вас.

3
ответ дан 4 December 2019 в 20:26
поделиться

FasterCSV исправляет класс Массива и уже добавляет 'to_csv' метод к нему, но он не делает то, что Вы хотите. Вы могли перезаписать его сами путем выполнения чего-то как:

class Array
  def to_csv(options = Hash.new)
    collect { |item| item.to_csv }.join "\n"
  end
end

Или что-то вдоль тех строк, но это довольно дрянно.

Честно, это имеет больше смысла путем, Вы сделали это как метод класса для Вашей модели.

2
ответ дан 4 December 2019 в 20:26
поделиться

Вы могли определить метод непосредственно на messages сам объект, но если бы Вы делаете это, метод, только был бы доступен тому определенному экземпляру:

def messages.to_csv()

   FasterCSV.generate do |csv|
     csv << ["from", "to", "received"]
     self.each { |m| csv << [m.from, m.to, m.created_at] }   
   end

end

Затем Вы могли назвать его как так:

messages.to_csv

Я - новичок Ruby, таким образом, я не уверен, является ли это идиоматический Ruby или нет: то есть, я не уверен, как распространенный или признал, что это должно определить новые методы непосредственно на экземплярах объектов, я только знаю, что это возможно ;-)

0
ответ дан 4 December 2019 в 20:26
поделиться

Если бы это изолируется к одной модели AR, я добавил бы to_custom_csv_array метод экземпляра

def to_custom_csv_array
  [self.from,self.to,self.created_at]
end

затем переопределение находит на классе

def self.find(*args)
  collection = super
  collection.extend(CustomToCSV) if collection.is_a?(Array)
end

и в CustomToCSV определяют to_custom_csv для генерации csv

module CustomToCSV
  def to_custom_csv
    FasterCSV.generate do |csv|
      csv << ["from","to", "received"]
      csv << self.map {|obj| obj.to_custom_csv_array}
    end
  end
end

Это из памяти, но должно работать.

0
ответ дан 4 December 2019 в 20:26
поделиться

Вы могли создать метод на своем Классе сообщений, чтобы сделать что-то вроде...

В Вашем контроллере....

@csv_file = Message.send_all_to_csv

В Вашей модели...

require 'fastercsv'
class Message < ActiveRecord::Base
  def send_all_to_csv
    @messages = Find.all
    FasterCSV.generate do |csv|
      csv << ["from","to", "received"]
      for message in @messages
        csv << [message.from,message.to,message.created_at]
      end
    end
    # do something with your csv object (return it to the controller
    # or pass it on to another class method
  end
end
0
ответ дан 4 December 2019 в 20:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: