Rails 2.3.8 named_scope chaining - PullRequest
       5

Rails 2.3.8 named_scope chaining

2 голосов
/ 08 июня 2011

У меня есть следующее вложенное выражение if hairball, мне интересно, есть ли более эффективный способ написания этого кода (меньше строк кода, которые не требуют так много условных выражений)

Каждый из методов named_scopes в модели.

box = (params[:b] ? params[:b] : "inbox")
show = (params[:s] ? params[:s] : "all")

if box == "inbox"
  if show == "all"
    @messages = @current_user.received_messages.all  
  elsif show == "unread"
    @messages = @current_user.received_messages.unread.all  
  elsif show == "read"
    @messages = @current_user.received_messages.read.all  
  elsif show == "starred"
    @messages = @current_user.received_messages.starred.all  
  else
    @messages = []
  end
elsif box = "sent"
  @messages = @current_user.sent_messages.all  
else
  @messages = []
end

Я думал, что мог бы использовать метод 'call' для box и показывать как

@current_user.received_messages.call(:box).call(:show).all

возможно ..

UGH, я должен был потратить немного больше времени на игры ... просто, как я и думал, я просто использовал неправильный метод РЕШЕНИЕ

@current_user.send(box).send(show)

Ответы [ 3 ]

3 голосов
/ 08 июня 2011

Вы можете использовать метод scoped() в рельсах 2.3.8 для цепочки областей действия:

main_method = case (params[:s]||"inbox")
when "inbox"
  :received_messages
when "sent"
  :sent_messages
end
# create a scope. Don't execute the scope yet. 
scope = @current_user.send(main_method).scoped({}) if main_method

# now chain the scope if needed
scope = begin
  if ["unread", "read", "starred"].include?(params[:s])
    scope.send(params[:s])
  elsif((params[:s] || "all") == "all")
    scope
  end
end if main_method == :received_messages

@messages = scope.nil? ? [] : scope.all

Ссылка:

Источник метода области действия вRails 2.3.x

Rails использует анонимные области в 2.3.x

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

Ваш ответ очень близок, но он не может преобразовать box значения.

box  = params[:b] || 'inbox'
show = params[:s] || 'all'

box_scope = case box
  when 'inbox' then 'received_messages'
  when 'sent'  then 'sent_messages'
end
show_scope = show # no convertion needed at this point, maybe in the future

# If box_scope is nil, don't query
@messages = box_scope.nil? ? [] : @current_user.send(box_scope).send(show_scope)

Это предполагает, что вы покончили с .all, который вы использовали в исходном коде для всех параметров, которые исчезли в вашем ответе.

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

Это то, что я понял, я не буду отмечать свой собственный ответ как правильный, если все не согласятся, что это лучшее - какие-либо другие идеи?

if params[:b].present? && ["received_messages", "sent_messages"].include?(params[:b])
  box = params[:b]

  if params[:s].present? && ["all", "unread", "starred"].include?(params[:s])
    show = params[:s]
  else
    show = "all"
  end

  @messages = @current_user.send(box).send(show)
else
  @messages = []
end
...