Richlewis
Richlewis

Reputation: 15384

update_attributes with transient Rspec/FactoryGirl

I am looking to find out if it is possible to update an objects attributes with a transient value, I have this test

it 'should be able to update an image category' do
  @image = FactoryGirl.create(:image, categories_count: 2)
  expect(@image.image_categories.count).to eq(2)
  @image.update_attributes(categories_count: 1)
  @image.save
  expect(@image.image_categories.count).to eq(1)
end

FactoryGirl.define do
  factory :image do
    title 'Test Title'
    description 'Test Description'
    transient do
      photo_name 'validated_image.jpg'
    end
    photo { File.new(File.join(Rails.root, 'spec/fixtures', photo_name)) }
    transient do
      categories_count 1
    end
    categories { build_list(:category, categories_count) }
  end
end

But it fails with

ActiveRecord::UnknownAttributeError:
unknown attribute 'categories_count' for Image.

How would i go about updating the categories_count for @image

Schema

create_table "images", force: :cascade do |t|
  t.string   "title"
  t.text     "description"
  t.string   "photo_file_name"
  t.string   "photo_content_type"
  t.integer  "photo_file_size"
  t.datetime "photo_updated_at"
  t.datetime "created_at",         null: false
  t.datetime "updated_at",         null: false
end

create_table "categories", force: :cascade do |t|
  t.string   "name"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

create_table "image_categories", force: :cascade do |t|
  t.integer  "image_id"
  t.integer  "category_id"
  t.datetime "created_at",  null: false
  t.datetime "updated_at",  null: false
end

Models

class Image < ActiveRecord::Base
  has_many :image_categories, dependent: :destroy
  has_many :categories, through: :image_categories
  has_attached_file :photo,
                styles: {
                  image_square_home: '350x350#',
                  image_thumb: '100x100#'
                }
  validates_attachment :photo, content_type: { :content_type => ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'], message: 'Images must be jpg/jpeg/gif/png format only' },
                           size: { in: 0..2000.kilobytes, message: 'Images should be less than 2 megabytes' }
  validates :title, presence: { message: "Don't forget to add a title" }
  validates :description, presence: { message: "Don't forget to add a description" }
  validates :categories, presence: { message: 'Choose At Least 1 Category' }
end

class Category < ActiveRecord::Base
  has_many :image_categories
  has_many :images, through: :image_categories
  validates :name, presence: { message: "Don't forget to add a Category" }
  validates_uniqueness_of :name, message: 'Category name %{value} already exists'
  validates_format_of :name, with: /\A([A-Za-z]+ )+[A-Za-z]+$|^[A-Za-z]+\z/, message: 'Only A-Z Characters Allowed', allow_blank: true, allow_nil: true
end 

When running the test i get the following output

 Failure/Error: @image.update_attributes(categories_count: 1)

 ActiveRecord::UnknownAttributeError:
   unknown attribute 'categories_count' for Image.
 # ./spec/models/image_spec.rb:71:in `block (4 levels) in <top (required)>'
 # ------------------
 # --- Caused by: ---
 # NoMethodError:
 #   undefined method `categories_count=' for #<Image:0x00000005483550>
 #   ./spec/models/image_spec.rb:71:in `block (4 levels) in <top (required)>'

Upvotes: 1

Views: 1525

Answers (1)

BroiSatse
BroiSatse

Reputation: 44725

Was looking into a wrong line all the time. Your factory is fine and you use it the right way. Factory returns an ActiveRecord object, which has no idea about how it was created and has absolutely no knowledge about how its factory has been generated:

@image.update_attributes(categories_count: 1)

update_attributes acts on the record itself, which has no idea about categories_count. It is also not clear what you want here to happen or what you are actually testing as looks you are testing FactoryGirl rather than your model.

Upvotes: 3

Related Questions