Рельсы 3: настройка атрибутов профиля пользователя и добавление второй модели для управления атрибутами?

#ruby-on-rails #ruby-on-rails-3 #model-view-controller

#ruby-on-rails #ruby-on-rails-3 #модель-представление-контроллер

Вопрос:

Я моделирую свою модель пользователя и добавляю атрибуты профиля.

Я хочу добавить набор социальных URL-адресов для пользователя, начиная примерно с 3 или 4 вариантов и, возможно, увеличиваясь до более чем 15. Мне было бы очень легко просто создать отдельный атрибут в модели пользователя для каждого URL-адреса, а затем просмотреть их все отдельно для страницы профиля. Хотя кажется, что это может быть излишним, будет ли это неуместным или мне следует продолжить, поскольку атрибуты просто хранят простую строку?

Если я не должен загружать их все в пользовательскую модель:

Каков наилучший способ сделать это с помощью отдельной модели? Любой, как я мог бы получить все социальные URL-адреса, созданные пользователем в массиве @social_urls?

Я также хочу связать конкретное уменьшенное изображение с каждым URL-адресом веб-сайта, который будет отображаться с помощью @social_urls.каждый блок do. Я не понимаю, как я буду динамически вызывать правильное изображение.

Большое спасибо за любую помощь или понимание.

Редактировать: будет ли это работать для прикрепления html-класса с именем социального сайта? а затем создать эскиз с помощью css?

 # In erb or (better) a helper
<% User::SOCIAL_SYSTEMS.each do |social_system| 
   url = @user.send(social_system)
   if url %>
     <p><a href="<%= url %>" class="<%=User::SOCIAL_SYSTEM_NAMES[social_system]%>"><%=
           User::SOCIAL_SYSTEM_NAMES[social_system] %></a></p>
<% end
end %>
  

Комментарии:

1. Не забудьте проголосовать за все ответы, которые вы считаете полезными, включая ответы на вопросы других людей.

Ответ №1:

Создание дополнительных атрибутов в модели пользователя для независимых фактов (URL-адреса социальных сетей) — это нормально.

Или у вас могут быть еще две модели только для социальных URL-адресов со структурой

 SocialUrl
  id
  user_id 
  social_system_id
  value

SocialSystem
  id
  name   # name of the social system ("Google  ", "Facebook", etc)
  

Но нет необходимости в дополнительной сложности двух дополнительных таблиц, если вы действительно не видите значения.

Re:

просматривая их все (атрибуты социальных URL)

Вы можете (и должны) создавать вспомогательные методы для своей пользовательской модели. Например, вы можете иметь имена социальных атрибутов в виде массива CONST, а затем использовать #send для извлечения всех их значений.

Добавлены компромиссы между двумя стилями (либо с использованием пользовательской модели, либо с созданием двух дополнительных моделей)—

  • Как часто вы будете добавлять новые социальные системы?

С точки зрения пространства хранилище БД настолько дешево, что это не имеет никакого значения. — Т.Е. стиль модели пользователя — это более редкое хранение данных.

  • Дополнительные две модели означают еще два контроллера, еще два набора представлений, тестирование, настройку безопасности, чтобы только администратор мог добавлять новую социальную систему и т. Д.

Я думаю, я бы сосредоточился на основной части своего приложения и просто использовал модель пользователя. Проще и приятнее.

Добавлены комментарии Re:

Для эскиза подойдет скрепка или что-то подобное. — Он создает дополнительную модель и таблицу, но плагин обрабатывает все детали.

Для отображения URL-адресов вы бы использовали один или два помощника. Например

 User model
  facebook_url string
  google_plus_url

# Constants defined in User model
SOCIAL_SYSTEMS = ['facebook_url', 'google_plus_url']
SOCIAL_SYSTEM_NAMES = {'facebook_url' => 'Facebook',
                       'google_plus_url' => 'Google  '}

# In erb or (better) a helper
<% User::SOCIAL_SYSTEMS.each do |social_system| 
   url = @user.send(social_system)
   if url %>
     <p><a href="<%= url %>"><%=
           User::SOCIAL_SYSTEM_NAMES[social_system] %></a></p>
<% end
end %>
  

Добавлен ps
Если вам нужно сохранить более одного факта для каждой социальной системы (например, URL-адрес профиля из социальной системы плюс последняя оценка пользователя из социальной системы), тогда я бы выбрал дополнительные таблицы. Но если вам нужен только один факт (например, URL-адрес профиля пользователя), то добавление в модель пользователя подойдет. (имхо)

Комментарии:

1. Спасибо за понимание, мне нравится простой способ перейти к пользовательской модели и придерживаться моего приложения для тяжелой работы, но как мне прикрепить миниатюру к представлению? а также в представлении профиля я должен был бы сделать, если @user.facebook_url.empty ? для каждой отдельной (возможно, 12) социальной сети?

2. Обновленный ответ на ваши комментарии

3. очень признателен! есть ли способ адаптировать SOCIAL_SYSTEM_NAMES в уменьшенное изображение?

4. Вы имеете в виду наличие миниатюр для каждой социальной сети? Просмотрите несколько эскизов для каждого экземпляра объекта / модели из paperclip, carrierwave и т. Д.

5. Привет, спасибо за совет, но я ничего не смог найти по этому вопросу. Я думал и пытался придумать способ создания значка с использованием стиля изображения css, будет ли вышеуказанное редактирование работать для прикрепления динамического класса к ссылке? Спасибо

Ответ №2:

вероятно, вы хотите иметь одну модель для хранения URL-адресов для каждого пользователя, а затем другую модель для управления эскизами для каждого сайта. если вам не нужны личные значки для каждого пользователя, в этом случае вы, вероятно, включите has_attached_file в модель пользователя, а не создаете модель социального сайта. paperclip — это преобладающий камень вложения для rails, отсюда и метод has_attached_file .

 class User < ActiveRecord::Base
  has_many :social_urls
end

class SocialUrl < ActiveRecord::Base
  belongs_to :user
  belongs_to :social_site
end

class SocialSite < ActiveRecord::Base
  has_attached_file :thumbnail
  has_many :social_urls
end
  

Комментарии:

1. Я согласен с использованием скрепки или аналогичного для хранения эскизов. Или просто используйте Gravatar

2. Я действительно использую carrierwave прямо сейчас в своем приложении, есть ли для этого обходной путь? Также не могли бы вы разбить атрибуты для модели SocialUrl, SocialSite и User? И объясните, что я бы добавил в представление профиля, чтобы увидеть значки?? Большое спасибо.

3. вероятно, поможет этот railscast: railscasts.com/episodes/253-carrierwave-file-uploads

Ответ №3:

Вам действительно нужна дополнительная модель для этого?

если вам нужно хранить растущее количество URL-адресов для сайтов социальных сетей или других веб-сайтов, вы можете сделать следующее:

1) определите миграцию для добавления текстового столбца :social_sites в вашу пользовательскую модель

 class AddSorialSitesToUsers < ActiveRecord::Migration
  def self.up
    add_column :users, :social_sites, :text
  end

  def self.down
    remove_column :users, :social_sites
  end
end
  

2) определите атрибут :social_sites как подлежащий сериализации

 class User < ActiveRecord::Base
   serialize :social_sites

end
  

3) Затем назначьте хэш или упорядоченный хэш user.social_sites и сохраните запись..

 u = User.find(1)
u.social_sites = {:facebook => 'http://facebook.com/somebody', :twitter => "http://twitter.com/somebody", ...}
  

поскольку это хэш, вы можете назначить столько разных имен служб в качестве ключей, сколько захотите .. а затем позже перебирать хэш-ключи для их извлечения … или напрямую обращаться к ним с именем сайта
, например:

 u = User.find(1)
puts u.social_sites[:facebook]
puts u.social_sites[:twitter]
...
  

Улучшение:

Если вы хотите хранить не только URL-адрес для каждого сайта, вы можете использовать вложенные хэши следующим образом:

 u.social_sites = {:facebook => {:url => "http://facebook.com/username", :icon => "url-or-filename-to-the-icon"} ,
                  :twitter =>  {:url => "http://twitter.com/username",  :icon => "url-or-filename-to-the-icon"}
                 }
  

Rails сериализует хэш (ы) в один атрибут:social_sites, и когда вы получаете к нему доступ, он отменяет его сериализацию — вы можете просто получить к нему доступ как к любому другому хэшу

    u = User.find(1)
   puts u.social_sites[:facebook][:url]
    => "http://facebook.com/username"

   puts u.social_sites[:facebook][:icon]
    => "url-or-filename-to-the-icon"
  

надеюсь, это поможет

Комментарии:

1. Привет, я не понимаю, как настроить форму, чтобы пользователи могли изначально сохранять URL-адрес для каждого возможного social_site и как в представлении я бы ссылался на URL-адрес, показывая изображение значка социального сайта

2. вы могли бы сами закодировать это как часть пользовательского представления .. например, с частичным

3. извините, я имел в виду, что я не понимаю, как я буду кодировать эту часть. Я новичок в rails и программировании..

4. Я бы рекомендовал railscasts.com — в частности, о сложных формах и сложных частичных элементах — найдите «сложный» на этом веб-сайте