Рельсы упорядочивают активные записи с assign_attributes - PullRequest
1 голос
/ 20 марта 2020

У меня есть пользовательская модель с моделью скоринга, которая имеет значение score. В моем представлении рельсы я хочу сделать заказ моих пользователей по счету. => User.joins (: scoring) .order (: score) Пока все хорошо. это усложняется, когда я динамически изменяю оценки некоторых пользователей, не изменяя их в базе данных в соответствии с определенными атрибутами, такими как геолокация. Я попробовал функцию assign_attributes, но она не изменилась, потому что функция .order вызывает поля оценки в базе данных.

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

Мой код:

  #Get scoring in other geolocation
  @fiches_proxi = Fiche.joins(:user).merge(User.joins(:scoring)).near([@geo.lat_long_DMS.to_f, @geo.lat_long_grd.to_f], proxi_calcule(@geo.population_2012.to_i),units: :km, :order => 'scorings.score DESC').order('scorings.score DESC').where.not(geo: @geo.id).limit(10)

  #Get scoring in real geolocation
  @fiche_order_algo_all = Fiche.joins(:user).merge(User.joins(:scoring)).where(geo_id: @geo)

  #Find all scores
  @fiches_all = Fiche.where(id:  @fiche_order_algo_all.pluck(:id) +  @fiches_proxi.pluck(:id))

  @pagy, @fiche_order_algo = pagy(@fiches_all.joins(:user).merge(User.joins(:scoring).order('scorings.score DESC')), items: 12)

  @fiche_order_algo.each do |f|
    if f.geo.id != @geo.id
      f.user.scoring.assign_attributes(score: (f.user.scoring.score - 10.0))
    else
       f.user.scoring.score
    end
  end

Мой счет обновлен, но мой заказ такой же!

1 Ответ

0 голосов
/ 20 марта 2020

Когда вы вызываете .each для вашего отношения, оно возвращает массив, поэтому вы можете использовать Array#sort_by

@fiche_order_algo.each do |f|
  if f.geo.id != @geo.id
    f.user.scoring.assign_attributes(score: (f.user.scoring.score - 10.0))
  else
     f.user.scoring.score
  end
end

@fiche_order_algo.sort_by!{|f| f.scoring.score}

Если вы работаете с большими наборами данных, это может быть не оптимизировано, но не будет менее эффективным, чем у вас уже есть.

Но вы также можете сделать это за один go с:

@fiche_order_algo.sort_by! do |f|
  if f.geo.id != @geo.id
    f.user.scoring.assign_attributes(score: (f.user.scoring.score - 10.0))
  end
  f.user.scoring.score
end
...