开发者

How to collect in Rails?

baza_managers = BazaManager.find(:all, 
  :conditions => ["or_unit_id != ?", 1]).collect { 
      |mou| [mou.email, mou.or_unit_id]}
开发者_如何学Python
respondent_emails = Respondent.find(:all).collect {|r| r.email }

ERROR:

from lib/scripts/baza_sync.rb:26:in `each'
from lib/scripts/baza_sync.rb:26

26 line ↓

baza_managers.each do |moi|
  if !respondent_emails.include?(moi)
    Respondent.create(:email => moi, :user_id => 1, :respondent_group_id => moi)
  end
end

ERROR I GET:

undefined method `email' for ["vadasd@test.test.com", 8]:Array (NoMethodError)

I don't know why I'm getting this error.


try with:

baza_managers = BazaManager.find(:all, 
  :conditions => ["or_unit_id != ?", 1]).collect { 
      |mou| [mou.email, mou.or_unit_id]}

respondent_emails = Respondent.find(:all).collect {|r| r.email }

baza_managers.each do |moi|
  if !respondent_emails.include?(moi[0])
    Respondent.create(:email => moi[0], :user_id => 1, :respondent_group_id => moi[1])
  end
end


Fix your code with following:

if !respondent_emails.include?(moi[0])
  Respondent.create(:email => moi[0], :user_id => 1, :respondent_group_id => moi[1])
end


I would think there is at least one error not in the way you are using collect but in the logic you write on the last lines when you go through the baza_managers array.

With this code the condition respondent_emails.include?(moi) will be always false because respondent_emails is an array of email addresses but moi is an array like ["vadasd@test.test.com", 8] so they will never match.

I think this mistake made you make an error in the line :

Respondent.create(:email => moi, :user_id => 1, :respondent_group_id => moi)

Because this line will be evaluate as (for example) :

Respondent.create(:email => ["vadasd@test.test.com", 8], :user_id => 1, :respondent_group_id => ["vadasd@test.test.com", 8])

Which is probably not what you want.

Last, I would suggest you to read the debugger rails guide, I often use debugger to figure out where and what is the problem in this kind of code and error.


I would rewrite your code as follows:

baza_managers = BazaManager.all(:conditions => ["or_unit_id != ?", 1]).
                  collect { |mou| [mou.email, mou.or_unit_id]}

respondent_emails = Respondent.find(:all).collect {|r| r.email }

baza_managers.each do |email, unit_id|
  unless respondent_emails.include?(email)
    Respondent.create(:email => email, :user_id => 1, 
      :respondent_group_id => unit_id)
  end
end

This solution can be further optimized by using OUTER JOIN to detect missing Respondents

BazaManager.all(
  :include    => "OUTER JOIN respondents A ON baza_managers.email = A.email",
  :conditions => ["baza_managers.or_unit_id != ? AND A.id IS NULL", 1]
).each do |bm|
  Respondent.create(:email => bm.email, :respondent_group_id => bm.or_unit_id,
    :user_id => 1)
end        

The solution can be made elegant and optimal by adding associations and named_scope.

class BazaManager

  has_many :respondents, :foreign_key => :email, :primary_key => :email  

  named_scope :without_respondents, :include => :respondents, 
    :conditions =>["baza_managers.or_unit_id != ? AND respondents.id IS NULL", 1]

end

Now the named_scope can be used as follows:

BazaManager.without_respondents.each do |bm|
  Respondent.create(:email => bm.email, :respondent_group_id => bm.or_unit_id,
    :user_id => 1)
end        
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜