factory_girl does not set model attribute - ruby-on-rails

factory_girl is not setting the url attribute on the model correctly. I looked to see if there are reserved words, but I found nothing.
factory :attachment do
association :attachable, factory: :upload
url "some/path"
description "Some important file"
end
I get this failure. Notice url: nil
1) Attachment should be valid
Failure/Error: it { should be_valid }
expected #<Attachment id: 1048, attachable_id: 1047, attachable_type: "Upload", name: nil, url: nil, created_at: nil, updated_at: nil, description: "Some important file"> to be valid, but got errors: Url can't be empty
# ./spec/models/attachment_spec.rb:14:in `block (2 levels) in <top (required)>'
I ran factory_girl in the console and got the same result with FactorGirl.attributes_for :attachment
Running Rails 4 with FactoryGirl 4.2.1.

I was having this same issue and after hours of banging my head on the desk I decided to stop and restart my Spring server. It started working like magic.
Before restarting my Spring server I was able to set attributes using create :object, new_field: true but just using create :object wouldn't work, even if I had new_field true in my factories.rb file.

Late to the party but I had the same problem. I had added all my attributes after the initial migration, and it turned out I was using attr_accessor instead of attr_accessible in my model.

Related

Multiple file upload carrierwave mongoid

I have been having issues with implementing multiple file upload with the carrierwave-mongoid gem. Multiple file upload with carrierwave is well documented for ActiveRecord but not Mongoid. I have tried to mirror the ActiveRecord tutorials are much as possible but cannot seem to get it right. My uploader is mounted as follows.
class Product
include Mongoid::Document
.....
attr_accessor :product_images, :product_images_cache
mount_uploaders :product_images, ProductImageUploader
end
The main issue that I am having is with saving the uploader instance. In my controller with a pry in the create block, I am able to create a Product instance that contains the uploader instances, but when I try to retrieve the Uploader instance via the rails console the array is empty. see below.
[22] pry(#<ProductsController>)> #product
=> #<Product _id: 58726dae75e505a9ddc43f20, name: "Post", description: "This is a post\r\n", rating: nil, category_id: 1, seller_id: 1, approved: false, approved_by: nil>
[23] pry(#<ProductsController>)> #product.product_images_urls
=> ["/uploads/tmp/1483894190-43485-0005-7191/download.jpeg", "/uploads/tmp/1483894190-43485-0006-6662/TRACK.jpg"]
[24] pry(#<ProductsController>)> Product.last
=> #<Product _id: 58726dae75e505a9ddc43f20, name: "Post", description: "This is a post\r\n", rating: nil, category_id: 1, seller_id: 1, approved: false, approved_by: nil>
[25] pry(#<ProductsController>)> Product.last.product_images_urls
=> []
What is notice here is that the images are not being save in the uploads directory. I have spent quite a bit of time researching this but no leads. Any help will be greatly appreciated.
Update: This method is currently not supported by CarrierWave-Mongoid. My initial thoughts where right the Uploader object was not being created/saved https://github.com/carrierwaveuploader/carrierwave-mongoid/issues/155. I am currently looking for a workaround for this - any pointer in this direction will be great

Paperclip and Zip - My .zip file is magically transforming into a .png

I'm having a problem with Paperclip. Easily enough, I am trying to get a .zip folder uploading using Paperclip - I've read around and it seems like it can be done.
However, my .zip uploads transform into the default 'missing.png' file - and I have no earthly idea why. The file is, er... well, the process is going through and I am not getting any errors, but obviously something is not turning out right.
I've followed the instructions of Can't upload zip files using ruby on rails and paperclip gem but it's still not... changing anything.
From what I can tell through a rails console run of the model in question, the file isn't uploading at all. The problem is, I'm not sure where or how or why.
Here's my book model
book.rb
has_attached_file :content
validates_attachment_content_type :content, :content_type => ["application/zip, application/x-zip"]
before_post_process :skip_for_zip
def skip_for_zip
! %w(application/zip application/x-zip).include?(attachment_content_type)
end
end
And a quick rails console peek
2.1.6 :001 > Book.all
Book Load (0.7ms) SELECT "books".* FROM "books"
=> #<ActiveRecord::Relation [#<Book id: 3, title: "Test", summary: "La la la", rating: nil, author_id: nil, word_count: nil, created_at: "2016-10-28 03:53:22", updated_at: "2016-10-28 03:53:22", cover_file_name: nil, cover_content_type: nil, cover_file_size: nil, cover_updated_at: nil, content_file_name: nil, content_content_type: nil, content_file_size: nil, content_updated_at: nil>, #<Book id: 4, title: "ugh", summary: "", rating: nil, author_id: nil, word_count: nil, created_at: "2016-10-28 03:59:33", updated_at: "2016-10-28 03:59:33", cover_file_name: nil, cover_content_type: nil, cover_file_size: nil, cover_updated_at: nil, content_file_name: nil, content_content_type: nil, content_file_size: nil, content_updated_at: nil>]>
2.1.6 :002 >
Ignore the 'cover' section, there was a separate Paperclip attachment that I hid to diagnose the 'content' problem.
But note, I'm not getting ANY errors. At all. Whatsoever. So. Any help from the StackOverflow Rails Gawds would be greatly appreciated for a newb like me.
Solved!
As #henners66 suggested, I was completely missing the :content as a permitted param on my books controller - further, turns out I was declaring the 'valid content types' incorrectly. It should have been:
book.rb
has_attached_file :content
validates_attachment_content_type :content, :content_type => ["application/zip", "application/x-zip"]
before_post_process :skip_for_zip
def skip_for_zip
! %w(application/zip application/x-zip).include?(attachment_content_type)
end
end
Thanks everyone!

having trouble testing upload file with Capybara attach_file method

I'm having trouble trying to test whether image upload works with paperclip using Capybara's attach_file method.
rspec returns these errors below:
Failures:
1) Upload Background Image cannot upload a background image
Failure/Error: page.attach_file('#artist_background_image', Rails.root + 'spec/Fixtures/Snow.jpg')
Capybara::ElementNotFound:
Unable to find file field "#artist_background_image"
# ./spec/models/artist_spec.rb:65:in `block (2 levels) in <top (required)>'
my test is listed below. I assumed the choose file button is the selector for attach_file so I used the id of the selector '#artist_background_page'.
describe 'Upload Background Image', js: true do
before :each do
p '================='
pp Artist.all
#artist = Artist.first || Artist.create(artist_name:'Double Stuff Oreos', email:'i#love.oreos', password:'letmein')
visit "/artists/" + #artist.id.to_s
pp #artist.id
pp #artist.artist_name
p #artist.errors.full_messages
click_button 'Log in'
fill_in 'Email', with: 'i#love.oreos'
fill_in 'Password', with: 'letmein'
page.find('#loginButtonModal').click
page.find('#addBackgroundImagePrompt').click
page.attach_file('#artist_background_image', Rails.root + 'spec/Fixtures/Snow.jpg')
p Rails.root + 'spec/Fixtures/Snow.jpg'
click_button 'upload'
end
it "cannot upload a background image", js: true do
backgroundURL = #artist.background_image.url.include?('Snow.jpg')
p #artist.background_image.url
expect(backgroundURL).to be_truthy
end
end
However when I change the selector to just 'artist_background_page' without the id '#' symbol. rspec gives me different error:
...."================="
[]
"is_active_session is called"
#<Artist id: 1, artist_name: "Double Stuff Oreos", route_name: "double-stuff-oreos", created_at: "2014-07-20 17:20:48", updated_at: "2014-07-20 17:20:48", password_digest: "$2a$04$vgozdgieklXPjJ9Ri4Cv1e1d/hme0ybNnSEGXrmob5z...", remember_token: nil, email: "i#love.oreos", description: nil, youtube: nil, twitter: nil, facebook: nil, instagram: nil, hometown: nil, confirmation_code: nil, is_confirmed: nil, background_image_file_name: nil, background_image_content_type: nil, background_image_file_size: nil, background_image_updated_at: nil>
1
"Double Stuff Oreos"
[]
"is_active_session is called"
#<Pathname:/Users/bob/rails_projects/audience/spec/Fixtures/Snow.jpg>
"/background_images/original/missing.png"
"Hello from update"
"Logged in!"
An error occurred in an after hook
ActiveRecord::RecordNotFound: Couldn't find Artist with 'id'=1
occurred at /Users/shuo/.rvm/gems/ruby-2.1.2/gems/activerecord- 4.1.4/lib/active_record/relation/finder_methods.rb:320:in `raise_record_not_found_exception!'
F....
Failures:
1) Upload Background Image cannot upload a background image
Failure/Error: expect(backgroundURL).to be_truthy
expected: truthy value
got: false
# ./spec/models/artist_spec.rb:74:in `block (2 levels) in <top (required)>'
In this case, the model was created but the errors says that it cannot find it for some reason...
Is there any other method I can use to attach files in capybara and test successfully uploads?
Possibilities for failure:
Wrong path for file upload
Wrong method to use or invalid use of method
something wrong with server
This error:
Capybara::ElementNotFound:
Unable to find file field "#artist_background_image"
shows that capybara can't find a field named #artist_background_image. What you need to do is to reference the file upload field by its name.
Suppose you have
<input id="artist_background_image" name="file_upload" type="file">
Then you can reference the field like:
page.attach_file('file_upload', Rails.root + 'spec/Fixtures/Snow.jpg')
With that, capybara will know what field to upload through.
I know this is a late response but I think it will help other people facing this issue.
This might be the case if you're using simple_form gem.
Note that it does automatically generate ids for your form elements, hence manually id-ing elements yourself is futile!
You can make sure of this by manually id-ing a form element then view the source on you browser. You'll defiantly see that your manually-assigned ids aren't anywhere in the page source.
There is; however, a naming convention that simple_form follows to id form elements.
object_attribute
The example bellow might clarify this even more (HAML exmaple):
= simple_form_for #user do |f|
= f.input :image, as: :file
simple_form will then automatically generate an id for the form element image as so (object_attribute):
id="user_image"
Now you can simply make use of this naming convention to target ids in your test. Hope this helps.

RSpec/Mongoid inheritance of defaults completely different result in test/development

This is one of those ones that makes you think you're going insane...
I have a class Section, and a DraftSection that inherits from it:
(Trimmed for brevity)
class Section
include Mongoid::Document
belongs_to :site
field :name, type: String
end
And
class DraftSection < Section
field :name, type: String, default: "New Section"
end
All simple stuff... console proves (again, trimmed for brevity):
004 > site = Site.first
=> #<Site _id: initech, name: "INITECH">
005 > site.sections.build
=> #<Section _id: 1, site_id: "initech", name: nil>
006 > site.draft_sections.build
=> #<DraftSection _id: 2, site_id: "initech", name: "New Section">
As you can see - the draft section name correctly defaults to "New Section" as it is overridden in the subclass.
Now when I run this spec:
describe "#new" do
it "should return a draft section" do
get 'new', site_id: site.id, format: :json
assigns(:section).should == "Something..."
end
end
Which tests this controller method:
def new
#section = #site.draft_sections.build
respond_with #section
end
Which fails (as expected), but with this:
Failure/Error: assigns(:section).should == "Something..."
expected: "Something..."
got: #<DraftSection _id: 1, site_id: "site-name-4", name: nil> (using ==)
What gives???
Update:
I figured it might be an issue with the different environment settings, so I looked at the mongoid.yml config file and saw this in the options:
# Preload all models in development, needed when models use
# inheritance. (default: false)
preload_models: true
I added it to the test environment settings too, but still no joy :(
Update 2 - the plot thickens...
Thought I'd try loading up the console in the test environment and trying the same as before:
001 > site = Site.first
=> #<Site _id: initech, name: "INITECH">
002 > site.draft_sections.build
=> #<DraftSection _id: 1, site_id: "initech", name: "New Section">
WTF?
Ok, no one's listening, but I'll post the solution here for future reference anyway...
For some reason, some time ago I had a debug session that meant I had left this code in my Spork.each_run block
# Reload all model files when run each spec
# otherwise there might be out-of-date testing
# require 'rspec/rails'
Dir["#{Rails.root}/app/controllers//*.rb"].each do |controller|
load controller
end
Dir["#{Rails.root}/app/models//*.rb"].each do |model|
load model
end
Dir["#{Rails.root}/lib//*.rb"].each do |klass|
load klass
end
This was causing the models to get reloaded on each run of a spec. Not surprisingly, this screwed up the way the classes were set up in memory whilst the specs were running.
Definitely explains why it was such a hard one to debug...
So for future googlers with similar inheritance problems in Rspec only - make sure that there's nothing reloading models anywhere in the test stack.

Rails: Can't assign model object values after migrating to 2.3.5

I'm migrating a Rails app from 2.0.2 to 2.3.5.
I have a model class:
class EventQuery < ActiveRecord::Base
set_table_name 'EventQueries'
def to_s; name; end
end
I'm debugging the problem in the console. I try to assign an EventQuery object an attribute:
./script/console production
Loading production environment (Rails 2.3.5)
>> q=EventQuery.new
=> #<EventQuery id: nil, role: nil, name: nil, description: nil, query: nil>
>> q.role="ADM"
> TypeError: can't convert String into Integer
from /usr/lib64/ruby/gems/1.8/gem /activerecord-2.3.5/lib/active_record/dirty.rb:135:in `[]='
(...)
In Rails 2.0.2 it works fine:
./script/console production
Loading production environment (Rails 2.0.2)
>> q=EventQuery.new
=> #< EventQuery id: nil, role: nil, name: nil, description: nil, query: nil
>> q.role='ADM'
=> "ADM"
Any ideas? Thank you!
I'm now thinking this must be related to plugin record_modified which is part of the application.
This problem is related to a name conflict with a method in the record_modified plugin. The console works fine if I exclude the plugin from loading.
I have decided to remove the record_modified plugin and refactor the code. Instead of using RecordModified methods I'm using ActiveRecord as follows:
RecordModified.modified? --> ActiveRecord.changed?
RecordModified.changed_columns --> ActiveRecord.changes + minor refactoring

Resources