find_by_sql или проблема с массивом - PullRequest
0 голосов
/ 10 февраля 2012

У меня проблемы, и я не могу сказать, есть ли это с find_by_sql, что-то с объектом массива или с моей логикой.Следующий код в помощнике.Это приложение имеет координатную сетку с 4 квадрантами.Я заменил имя приложения на Something, поэтому любые ссылки на него должны защищать приложение на данный момент.Я знаю, что этот код может быть запутанным, но я хотел, чтобы он работал первым, прежде чем что-то ещеВ основном проблема заключается в следующем: когда я запускаю SQL-запрос, я получаю ожидаемые результаты.Когда он сталкивается с координатами, которые являются дочерними элементами одного и того же родителя, он правильно рисует одну из них, но когда он добирается до удаления, он удаляет обе координаты из массива.Если это имеет значение, идентификаторы таблицы соединения возвращаются как идентификатор родительской координаты.Я попытался выбрать только то, что мне нужно, и это не помогло (в соответствии с решением из этой темы: http://www.sitepoint.com/forums/showthread.php?415007-rails-join-creates-wrong-id). Любая помощь будет принята с благодарностью.

Для дальнейшего уточнения, есть 16 родителейкоординаты в квадранте. Если оно пустое, мы рисуем пустое (согласно первому if), если оно не пустое, мы должны нарисовать div, чтобы собрать все дочерние элементы (сначала, если из остального), то мыПредполагается, что он рисует всех детей там, закрывает div и двигается дальше. Надеюсь, это поможет.

def buildQuadrantForUser(options={})
buffer=""

user_coordinates = SomethingUser.find_by_sql('
Select * from something_users
inner join coordinates as a on 
`something_users`.coordinate_id = `a`.id
inner join coordinates as b on
b.id = a.ancestry
Where ((user_id = '+options[:user].id.to_s+') AND (visibility = 2) AND (a.quadrant = '+options[:quadrant].to_s+')) 
Order By b.number ASC
')

i=0
while i<16 do
  i+=1
  first = true
  drawn = false
  l3num = 0
  user_coordinates.collect{|coor|
    puts "quadrant #{options[:quadrant].to_s}"
    if !coor.number.to_i.eql?(i)
      puts "quadrant: #{options[:quadrant].to_s}, number: #{i.to_s}, coordinate #{coor.id}"
      if drawn == false
        buffer<<"<div id=q"+options[:quadrant].to_s+"_"+i.to_s+" class='l2_div sc0'>" 
        buffer<<"</div>"
        drawn = true
      end
    else
      puts "quadrant: #{options[:quadrant].to_s}, number: #{i.to_s}, coordinate #{coor.inspect}"
      drawn = true
      if first == true
        buffer<<"<div id=q"+options[:quadrant].to_s+"_"+coor.number.to_s+" class='l2_div sc#{coor.coordinate.parent.percent_clicks_user_children(:user=>options[:user])}' data-value=#{coor.coordinate.parent.name} something-rating=#{coor.coordinate.parent.id.to_s}>"
        first = false
      end#end first
      l3num = l3num + 1
      if coor.coordinate.static?
        if !current_user.blank? && coor.user_id == current_user.id
          buffer<<content_tag(:div, content_tag(:span, "", :id=>'You'),:class=>"l3_#{l3num.to_s} cic#{coor.coordinate.percent_clicks_user(:user=>options[:user])}", :user=>'You', :somethingsomething=>coor.something_id.to_s,:something=>coor.something_id.to_s,:id=> "e" + coor.something_id.to_s, :rating=>coor.coordinate.name.to_s, :tag=>coor.something.tags.collect{|tag| tag.name+","}, :date=>time_ago_in_words(coor.updated_at), :source=>coor.something.url.split('/')[2], :link=>coor.something.url)
        else
          buffer<<content_tag(:div, content_tag(:span, "", :id=>coor.user.name),:class=>"l3_#{l3num.to_s} cic#{coor.coordinate.percent_clicks_user(:user=>options[:user])}", :user=>coor.user.name, :something=>coor.something_id.to_s,:id=> "e" + coor.something_id.to_s, :rating=>coor.coordinate.name.to_s, :tag=>coor.something.tags.collect{|tag| tag.name+","}, :date=>time_ago_in_words(coor.updated_at), :source=>coor.something.url.split('/')[2], :link=>coor.something.url)
        end
      else
        l3num = l3num-1 if l3num !=0
        if !current_user.blank? && coor.user_id == current_user.id
          buffer<<content_tag(:div, content_tag(:span, "", :id=>'You'),:class=>"l3_5 cic#{coor.coordinate.percent_clicks_user(:user=>options[:user])}", :user=>'You', :user=>coor.something.title,:something=>coor.something_id.to_s,:id=> "e" + coor.something_id.to_s, :rating=>coor.coordinate.name.to_s, :tag=>coor.something.tags.collect{|tag| tag.name+","}, :date=>time_ago_in_words(coor.updated_at), :source=>coor.something.url.split('/')[2], :link=>coor.something.url)
        else
          buffer<<content_tag(:div, content_tag(:span, "", :id=>coor.user.name),:class=>"l3_5 cic#{coor.coordinate.percent_clicks_user(:user=>options[:user])}", :user=>coor.something.title, :something=>coor.something_id.to_s,:id=> "e" + coor.something_id.to_s, :rating=>coor.coordinate.name.to_s, :tag=>coor.something.tags.collect{|tag| tag.name+","}, :date=>time_ago_in_words(coor.updated_at), :source=>coor.something.url.split('/')[2], :link=>coor.something.url)
        end
      end#end static
    buffer<<"</div>"
    puts "deleting #{coor.inspect}"
    user_coordinates.delete(coor)
    end#end coordinate.number = i.to_s
  }

end#end while
return buffer

end

Ответы [ 2 ]

2 голосов
/ 10 февраля 2012

Array#delete удаляет любые объекты, которые соответствуют аргументу, который вы ему даете.

Для объектов Active Record равенство определяется как имеющий одинаковый идентификатор.

Вы делаете select *, но активная запись не видит table1.id, table2.id и т. Д. - столбцы затеняют друг друга, поэтому, когда вы тоже coor.id, вы получите один из столбцов id из результата задавать.

Учитывая, что именно это определяет равенство, это, очевидно, плохо - скажем, например, что активная запись произвольно выбрала b.id в качестве своего идентификатора, а затем, когда вы удалите эту строку из массива, вы удалите каждую строку, где b.id имел это значение. Я предполагаю, что вы играете с тем, что вы выбираете, если только вы не выберете что-то такое, чтобы у каждого объекта был свой идентификатор Array#delete не будет играть в мяч

Кроме того, вам не следует изменять коллекцию во время ее итерации.

0 голосов
/ 12 февраля 2012

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

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