Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Local Jump Error No block given (yield) error on find_each

I'm trying to step through a list of records that are retrieved with find_each.

I patterned my controller code on the answer in this stack overflow post, but I'm still getting a "No Block Given (Yield)" error.

I'm just getting started in Ruby and Rails and I haven't yet found a full fledged explanation (lots of basic examples though) of blocks and yield that gives me what I need.

My code looks like this:

def select_save
    @class = params[:class]
    @student_id = params[:id]
    @class.each do |id|
      old_subject = Subject.find(id)
      new_subject = old_subject.dup
      new_subject.student_id = @student_id
      new_subject.save
      Assignment.find_each.where(:subject_id => id) do |assignments|
        assignments.each do |a|
          new_assignment = a.dup
          new_assignment.subject_id = new_subject.id
          new_assignment.save
        end
      end
    end

    respond_to do |format|
      format.html { redirect_to @student, :notice => 'Subject and assignments created.' }
    end
  end

and the error points to the line with find_each.

I know I need a block to yield to, but how exactly that would look in this particular case escapes me.

Thanks for any suggestions.

like image 936
lonC Avatar asked Aug 15 '12 02:08

lonC


1 Answers

You're passing a block to where and no block to find_each. You can't do that. You need to reverse find_each and where on this line, the order is important as the block is passed to the last method invoked:

Assignment.find_each.where(:subject_id => id) do |assignments|

It should read:

Assignment.where(:subject_id => id).find_each do |assignments|

Your next problem is you're trying to iterate over assignments, which is a single Assignment. find_each is already doing the iteration for you, passing one assignment into the block at a time. The block should read:

Assignment.where(:subject_id => id).find_each do |assignment|
  new_assignment = assignment.dup
  new_assignment.subject_id = new_subject.id
  new_assignment.save
end

I'm going to make the assumption that your Subject has many Assignments, since you have a subject_id inside your Assignment class. If this is the case, the final and most correct way to write your loop would be:

old_subject.assignments.each do |assignment|
  new_assignment = assignment.dup
  new_assignment.subject_id = new_subject.id
  new_assignment.save
end
like image 180
meagar Avatar answered Oct 21 '22 19:10

meagar