#ruby-on-rails #paperclip
#ruby-on-rails #скрепка
Вопрос:
В настоящее время я пытаюсь заполнить базу данных разработки в проекте кучей поддельных данных, чтобы смоделировать, как это будет выглядеть и работать с сотнями статей / пользователей. Я изучал разные драгоценные камни для выполнения задачи — например, Factory Girl, но документации очень не хватало, и я ее не понял — но в итоге использовал Populator и Faker gems и выполнил следующую задачу rake…
namespace :db do
desc "Testing populator"
task :populate => :environment do
require "populator"
require "faker"
User.populate 3 do |user|
name = Faker::Internet.user_name
user.name = name
user.cached_slug = name
user.email = Faker::Internet.email
user.created_at = 4.years.ago..Time.now
end
end
end
Отлично работает … для текстовых данных. Однако у всех пользователей есть аватар, который можно загрузить с помощью вложения скрепки, а также у всего обычного контента есть вложения с миниатюрами таким же образом.
Я понимаю, что gem-заполнитель просто выполняет прямое заполнение базы данных и не обязательно для этого выполняет проверку ActiveRecord .. поэтому я бы предположил, что Paperclip не может запускаться для генерации всех различных эскизов и необходимых (и загруженных в соответствующий каталог) для аватара, если я просто заполнил поле путем к файлу в задаче rake выше.
Есть ли способ заполнить поддельные изображения, через Populator или другим способом? Или, возможно, способ указать задаче rake на каталог со стоковыми изображениями на моем жестком диске, чтобы автоматически генерировать случайные эскизы для каждой записи? Поискал способ в Google, но не нашел много информации по этому вопросу.
Обновить
Окончательное решение, основанное на концепции pwnfactory…
namespace :db do
desc "Testing populator"
task :populate => :environment do
require "populator"
require "faker"
User.populate 3 do |user|
name = Faker::Internet.user_name
user.name = name
user.cached_slug = name
user.email = Faker::Internet.email
user.created_at = 4.years.ago..Time.now
end
User.all.each { |user| user.avatar = File.open(Dir.glob(File.join(Rails.root, 'sampleimages', '*')).sample); user.save! }
end
end
В основном это повторяет цикл и загружает аватары из каталога sampleimages для всех записей.
Ответ №1:
Чтобы связать случайное изображение в вашей задаче, вы могли бы попробовать следующее:
user.avatar = File.open(Dir.glob(File.join(Rails.root, 'sampleimages', '*')).sample)
где sampleimages — это каталог, содержащий аватары, которые должны быть связаны случайным образом
Комментарии:
1. Попробовал это и вставил эту строку в мою задачу rake выше (и создал каталог sampleimages в моем проекте rails), но он выдал «rake прерван! неопределенный метод `avatar=’ для #<Заполнитель::Запись:0x103fed130>» при запуске задачи. Поскольку база данных разбивает столбцы на три (avatar_file_name, avatar_content_type, avatar_file_size), это может быть причиной.
2. Вы должны использовать имя, которое вы определили в своей модели, например:
class Photo < ActiveRecord::Base has_attached_file :foto end
Здесь вы хотели бы использовать photo. foto = …3. Это то, что я делаю, вложение в мою пользовательскую модель называется ‘avatar’ (has_attached_file: avatar).
4. Извините, не понял, что Populate не использует реальные экземпляры модели. Одной из идей было бы создать второй цикл с использованием экземпляров AR для установки аватаров. Например:
User.all.each{ |user| user.avatar = File.open(Dir.glob(File.join(Rails.root, 'sampleimages', '*')).sample);user.save}
хотя это может несколько нарушить цель заполнения5. Верно, немного подтасовано, но это работает. Мне пришлось внести небольшую правку в ваш код (вставил исправленную версию выше), но в основном после генерации пользователей с помощью Populate он возвращается и загружает аватары для каждого из них. Единственное, что меня огорчает, это то, что я думаю, что это перезаписывает тех, у кого уже есть загруженные аватары, но отсюда должно быть очень просто работать в условиях, нацеленных только на нулевых пользователей. Большое вам спасибо.
Ответ №2:
user.avatar = File.open(Dir['app/assets/images/*.jpg'].sample)
Ответ №3:
Один из способов обойти это — ввести условие в мои представления.
Допустим, ваша модель — «пользователь», и у нее есть аватар. Затем вы можете сделать следующее:
<% if product.avatar.exists? %>
... show the attached photo
<% else %>
.. show a default photo
<% end %>
Это работает для меня с Paperclip, и я постоянно использую его в своей базе данных разработчиков, вместо того, чтобы беспокоиться о том, чтобы все изображения были прикреплены ко всем пользователям.
Комментарии:
1. Не по теме, но есть другой способ сделать это … если вы используете default_url в вашем has_attached_file в вашей модели, вызов paperclip в ваших представлениях вернется к изображению по умолчанию, если загруженное изображение не найдено. Удобно и сокращает код просмотра. Что касается моей ситуации, у меня уже есть пользователи, настроенные таким образом, но я хочу видеть некоторую случайность … не говоря уже о том, что к контенту ДОЛЖНО быть прикреплено изображение, запасной версии нет.