Добавление другого условия в существующий named_scope - PullRequest
1 голос
/ 29 июня 2011

Я работаю над приложением Rails 2.3.9, и мой вопрос касается как самореференциальных отношений, так и named_scope. Это приложение позволяет пользователям регистрироваться и делиться тренировками. Тренировка может быть публичной или частной, и она обозначается @workout.public == 1.

Я разрешаю пользователям «следить» за людьми. Таким образом, на панели мониторинга current_user я отображаю все общедоступные тренировки пользователей, которые выполняет current_user со следующим кодом:

/ панель / index.html.erb

 <% current_user.friends_workouts.each do |workout| %>
  <%= link_to (workout.title), workout %> <br/>
  by <%= link_to (workout.user.username), workout.user %> - <%= time_ago_in_words(workout.created_at)%> ago</p>
 <% end %>

user.rb

def friends_workouts
 @friends_workouts ||= Workout.current.public_workouts.find_all_by_user_id(self.friends.map(&:id), :order =>  "created_at DESC", :limit => 3)
end

workout.rb

named_scope :public_workouts, :conditions => {:public => 1 }, :order => "created_at DESC"

Теперь я хочу добавить условие в эту область, поскольку я добавляю еще один уровень общего доступа. Пользователи могут связываться с «ящиком» (действительно спортзал) через модель «членства». Таким образом, если current_user принадлежит к тому же «ящику», что и пользователь, за которым он следует, он должен видеть не только тренировки, помеченные как открытые, но и тренировки, где @workout.box_only == 1.

Как я могу повлиять на вышесказанное, чтобы включить все публичные тренировки от подписчиков и тренировки от подписчиков, где @workout.box_only == 1 and @workout.user.membership.box_id == current_user.membership.box_id. Я знаю, что синтаксис неправильный, но вы поняли мою точку зрения (надеюсь).

UPDATE:

Также необходимо учитывать, что: public_workouts вызывается со страниц, которые не требуют logged_in? пользователь, так что в этом случае, если область пытается ссылаться на current_user, он выдаст ошибку.

ОБНОВЛЕНИЕ 2: : пользователь has_many: членство

1 Ответ

0 голосов
/ 29 июня 2011

Я считаю, что что-то вроде следующего должно сделать это для вас:

named_scope :public_workouts, 
            :joins => ", user, membership"
            :conditions => 
              "workouts.public = 1 or
               membership.box_id = #{current_user.membership.box_id}",
            :group => "workouts.id",
            :order => "workouts.created_at DESC"

Тебе придется немного поиграть с этим. Сложная часть каждый раз, когда я пытаюсь сделать что-то подобное, - это исправить условия ИЛИ. Вы хотите, чтобы все общедоступные и те, где совпадает присоединяемый members.box_id, независимо от общедоступного значения 1.

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

def self.public_workouts
  query = Workout.joins(:user => { :membership })
  if current_user
    query.where('memberships.box_id = ? or workouts.public = 1', current_user.membership.box_id) unless current_user.membership.box_id.nil?
  else
    query.where('workouts.public = 1')
  end
  query.group('workouts.id')
  query.order("workouts.created_at DESC")
  return query
end

Edit2 Другой альтернативой может быть создание двух отдельных областей и создание метода класса, который объединяет две области. Этот метод класса будет затем использоваться в представлении.

named_scope :box_workouts, 
            :joins => ", user, membership"
            :conditions => "memberships.box_id = #{current_user.membership.box_id}"
            :group => "workouts.id",
            :order => "workouts.created_at DESC",
            :select "workouts"

named_scope :public_workouts, 
            :conditions => :public => 1
            :order => "workouts.created_at DESC"    

def self.public_box_workouts
  return box_workouts.merge(public_workouts).limit(3) if current_user
  return public_workouts.limit(3)
end     

Edit3 Не так сложно, я думаю, что-то вроде ниже будет работать.

def self.box_and_public_workouts(user)
  return public_workouts if user.nil? or user.memberships.blank?
  return public_workouts + box_workouts(user.memberships.map(&:box_id))
end

named_scope :box_workouts, lambda { |box_ids| { :conditions => ['box_id IN (?)', box_ids], :order => 'created_at DESC' } }

Извините за то, что так долго. Я скучал, путаясь с тем, как «старый» способ запроса базы данных. Я пошел прямо для Rails3:)

Во всяком случае, я не хотел ничего совершать, поэтому я попытался раскошелиться, чтобы отправить запрос на извлечение, но github мне сегодня грубоват. Тогда просто скопируйте отсюда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...