testing accepts_nested_attributes fails

25 views
Skip to first unread message

Javix

unread,
Feb 22, 2013, 5:00:56 AM2/22/13
to rs...@googlegroups.com
I wonder if 'accepts_nested_attributes_for :time_entries, :reject_if => proc { |attributes| attributes['worktime'].blank? }' works only in browser side.
The problem is that it fails in the following spec:

describe "time entry associations" do
    before do
      @timesheet.save      
    end
    let(:project) { create(:project) }
    let(:task) { create(:task, project: project)}    
    let!(:entries) { create(:time_entry, timesheet: @timesheet, task: task, workdate: Date.today.beginning_of_week) }
    
    it "should destroy associated time entries" do
      time_entries = @timesheet.time_entries.dup
      @timesheet.destroy
      time_entries.should_not be_empty
      time_entries.each do |entry|
        TimeEntry.find_by_id(entry.id).should be_nil
      end
    end
    
    it "should not save a time entry if worktime is empty" do
      valid_entry = build(:time_entry, timesheet: @timesheet, task: task)
      wrong_entry = build(:time_entry, timesheet: @timesheet, task: task, worktime: '')      
      expect {
        @timesheet.time_entries << valid_entry << wrong_entry
      }.to change { @timesheet.time_entries.size }.by(2)       
    end
  end

The model are defined as follows:

class Timesheet < ActiveRecord::Base
  attr_accessible :status, :user_id
  belongs_to :user
  has_many :time_entries, dependent: :destroy
  accepts_nested_attributes_for :time_entries, :reject_if => proc { |attributes| attributes['worktime'].blank? }
... 
end

class TimeEntry < ActiveRecord::Base
  attr_accessible :task_id, :timesheet_id, :workdate, :worktime  
  
  belongs_to :timesheet
  belongs_to :task
  
  validates :task_id, presence: true
  validates :timesheet_id, presence: true
  validates :workdate, presence: true
  validates :worktime, inclusion: { in: [0.5, 1] }            
end

When I run the spec, the 2 time entries are saves instead of 1 expected:

Failures:

  1) Timesheet time entry associations should not save a time entry if worktime is empty
     Failure/Error: expect {
       result should have been changed by 1, but was changed by 2
     # ./spec/models/timesheet_spec.rb:49:in `block (3 levels) in <top (required)>'

Finished in 1.15 seconds
8 examples, 1 failure

What is wrong with that?
Thank you.

Javix

unread,
Feb 22, 2013, 5:05:18 AM2/22/13
to rs...@googlegroups.com
adding just the below to TimeEntry model fixed the problem and makes the test pass:

class TimeEntry < ActiveRecord::Base
...
  validates :worktime, presence: true, inclusion: { in: [0.5, 1] }
...
end

Regards

Javix

unread,
Feb 22, 2013, 5:11:12 AM2/22/13
to rs...@googlegroups.com
SORRY, it has NOT solved the problem, Any ideas?

David Chelimsky

unread,
Feb 22, 2013, 8:24:37 AM2/22/13
to rs...@googlegroups.com
accepts_nested_attributes is a function of the owner (Timesheet), not
the association (TimeEntry / time_entries). This:

@timesheet.time_entries << valid_entry << wrong_entry

operates direction on the time_entries association. If you want to
test nested attributes you have to create a Timesheet model with
time_entries in the params. I don't recall the syntax for this, but
it's probably something like:

Timesheet.new :time_entries => [ { :worktime => nil }, { :worktime
=> :something_not_nil } ]

HTH,
David
> --
> You received this message because you are subscribed to the Google Groups
> "rspec" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to rspec+un...@googlegroups.com.
> To post to this group, send email to rs...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/rspec/-/8BLnK0cTKq0J.
>
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Serguei Cambour

unread,
Feb 24, 2013, 5:04:11 AM2/24/13
to rs...@googlegroups.com

On 22 Feb 2013, at 14:24, David Chelimsky <dchel...@gmail.com> wrote:

> accepts_nested_attributes is a function of the owner (Timesheet), not
> the association (TimeEntry / time_entries). This:
>
> @timesheet.time_entries << valid_entry << wrong_entry
>
> operates direction on the time_entries association. If you want to
> test nested attributes you have to create a Timesheet model with
> time_entries in the params. I don't recall the syntax for this, but
> it's probably something like:
>
OK, thank you, David, I'll try it later, it becomes a little bit more complicated than I supposed. More of that, I'm asking myself if it is really needed to test associations.

Regards,

Serguei
Reply all
Reply to author
Forward
0 new messages