Ruby on Rails: СУШКА повторяющегося блока кода, который инициализирует несколько переменных - PullRequest
0 голосов
/ 09 декабря 2010

У меня есть повторяющийся кодовый блок, который инициализирует несколько переменных в куче различных методов контроллера.Есть ли способ для меня сделать этот СУХОЙ с помощью модельного метода, в отличие от повторения одного и того же блока кода в каждом методе контроллера?

По сути, это для социального сайта, и он вытягивает список друзей пользователяи затем создание групп друзей на основе разрешений, которые пользователь имеет, которые хранятся в модели дружбы.Эта повторная инициализация ячеек - это то, что я пытаюсь сделать СУХИМ.

Обычно я бы использовал метод модели, но в этом случае 3 отдельные переменные инициализируются на основе одного обращения к базе данных, и это вызывается достаточно часто, я не хочу делать его излишне неэффективным, нажимаяБаза данных 3 раза.В C я бы просто использовал указатели, переданные в качестве переменных.

Это выглядит примерно так:

def example_method
  friendships = @user.friendships
  view_permission_friends = []
  write_permission_friends = []
  message_permission_friends = []
  for friendship in friendships
    if friendship.view_permission then view_permission_friends << friendship.friend_id end
    if friendship.write_permission then write_permission_friends << friendship.friend_id end
    if friendship.message_permission then message_permission_friends << friendship.friend_id end
  end
  #Do something with the 3 initialized arrays here
end

Ответы [ 3 ]

1 голос
/ 09 декабря 2010

Я немного подумал об этом и думаю, что этот код должен войти в вашу модель User. (Или любой класс @user в вашем примере выше.) Две причины:

  1. Это очень специфично для пользователя, его отношений и, самое главное, как они хранятся и извлекаются из базы данных.
  2. Код необходимо написать только один раз: в модели User.

Быстрый и простой способ, который использует внутреннее кэширование запросов в Rails, будет выглядеть следующим образом. Добавлено в модель User:

def view_permission_friends
  return friendships.select{|f| f.view_permission}
end

(etc.)

Ваши контроллеры просто делают это:

@viewers = @user.view_permission_friends
(etc.)

(Примечание: здесь больше возможностей для оптимизации и большей гибкости благодаря ленивому кэшированию и параметризации разрешения.)

0 голосов
/ 09 декабря 2010

Использование Enumerable#inject, Enumerable#find_all и Object#instance_variable_set:

def example_method
  %w{view write message}.inject({}) do |memo, s|
    friendships = @user.friendships.find_all{ |f| f.send("#{s}_permission") }
    memo["#{s}_permission_friends"] = friendships
  end.each do |key, value|
    instance_variable_set "@#{key}", value
  end

  # now you have 3 arrays:
  # @view_permission_friends, @write_permission_friends and @message_permission_friends
end
0 голосов
/ 09 декабря 2010

Как насчет ...

rv = {}
%w(view write message).each do |type|
  rv["#{type}_permission_friends"] = @user.friendships.select{|f|f.send(:"#{type}_permission")}.collect(&:friend_id)
end

Это дает вам хэш с ключами вместо отдельных массивов, но этого должно быть достаточно.

...