find_by_sql或数组问题

时间:2012-02-10 15:54:48

标签: ruby-on-rails

我遇到了问题,我无法判断它是否与find_by_sql,数组对象或逻辑有关。以下代码位于帮助程序中。这个应用程序有一个带有4个象限的坐标网格。我将应用程序名称替换为Something,因此任何引用都是为了保护应用程序。我知道这段代码可能会令人费解,但我想先让它先工作。基本上,问题是:当我运行SQL查询时,我得到了我期望的结果。当它到达同一父节点的子坐标时,它将正确地绘制其中一个,但是当它到达删除时,它将从数组中删除两个坐标。如果它有所不同,则连接表ID将作为父坐标的id返回。我尝试只选择我需要的东西,但没有帮助(根据此线程的解决方案: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

2 个答案:

答案 0 :(得分:2)

Array#delete删除任何与您提供的参数相等的对象。

对于Active Record对象,相等性定义为具有相同的id。

您正在进行select *但是有效记录看不到table1.idtable2.id等等 - 这些列相互遮挡,所以当你coor.id时你也会得到b.id结果集中的一个id列。

鉴于这是定义相等的原因,这显然是一件坏事 - 例如,活动记录任意选择b.id作为其id,然后当您从数组中删除该行时,您将删除每一行其中Array#delete具有该值。我猜你一直在玩你选择的东西,除非你选择的东西是这样的,每个对象都有不同的身份{{1}}不会打球

另外,在迭代它时,你真的不应该修改它。

答案 1 :(得分:0)

通过限制所有ID被选中来管理以在几个小时的工作之后修复此问题。我最终没有删除任何东西,不得不重组很多代码。对于那些试图找出其联接中奇怪ID的人,肯定会限制你选择的内容。