I got this error when trying to seed database with image file in nested attributes.
rails aborted!
ArgumentError: wrong number of arguments (given 1, expected 0; required keywords: io, filename)
product.rb
class Product < ApplicationRecord
belongs_to :user
has_many :founders, dependent: :destroy
accepts_nested_attributes_for :founders, allow_destroy: true
founder.rb
class Founder < ApplicationRecord
belongs_to :product, optional: true
has_one_attached :profile_picture
end
seed.rb
user = User.create!(email: 'user#example.com', password: '1234567890')
10.times do |index|
#product = Product.create(
user: user,
name: "Product #{index+1}",
tagline: Faker::Lorem.sentence,
industry: Faker::Company.industry,
website: Faker::Internet.url,
company_name: Faker::Company.name,
company_website: Faker::Internet.url,
founders_attributes: [
{
name: Faker::Name.name,
email: Faker::Internet.email,
website: Faker::Internet.url,
profile_picture: { io: File.open(Rails.root + "app/assets/images/profile_picture.png"), filename: 'profile_picture.png', content_type: 'image/png' }
},
{
name: Faker::Name.name,
email: Faker::Internet.email,
website: Faker::Internet.url,
profile_picture: { io: File.open(Rails.root + "app/assets/images/profile_picture.png"), filename: 'profile_picture.png', content_type: 'image/png' }
}
]
)
end
I have no idea to solve this error.
Give me some advice please.
You can do it without nested attributes. And by the way you didn't close your files:
PNG_PATH = Rails.root.join('app', 'assets', 'images', 'profile_picture.png')
user = User.create!(email: 'user#example.com', password: '1234567890')
1.upto(10) do |index|
#product = Product.create(
user: user,
name: "Product #{index}",
tagline: Faker::Lorem.sentence,
industry: Faker::Company.industry,
website: Faker::Internet.url,
company_name: Faker::Company.name,
company_website: Faker::Internet.url
)
2.times do
founder =
#product.founders.create(
name: Faker::Name.name,
email: Faker::Internet.email,
website: Faker::Internet.url
)
File.open(PNG_PATH) do |file|
founder.profile_picture.attach(io: file, filename: File.basename(file.to_path))
end
end
end
Related
I'm creating seed data and I can't figure out how to link the user's email to the auction model in the seller attribute on the seeds page, and I can't figure out how to link the user to the review seed data.
seeds.rb
u1 = User.create!(
name: 'Alice Johnson',
email: 'alice#email.com',
password: 'password',
rating: '3',
location: 'Memphis, TN'
)
u2 = User.create!(
name: 'Bob Jones',
email: 'bob#email.com',
password: 'password',
rating: '4',
location: 'Nashville, TN'
)
a2 = Auction.create!(
seller: , #Help
auction_start_time: DateTime.strptime("4/23/2020 08:00", "%m/%d/%Y %R"),
auction_end_time: DateTime.strptime("5/1/2020 11:59", "%m/%d/%Y %R"),
category: "Home",
current_price: 70.0,
highest_bid: 100.0,
highest_bidder: "John Doe",
name: "Vacuum",
active: TRUE
)
r1 = Review.create!(
user:u2,
description: 'The best',
rating:5,
reviewer: 'bob#email.com',
title:'Great',
user_reviewed:'Alice Johnson'
)
db/migration/addUSerFkColToReviews
class AddUserFkColToReviews < ActiveRecord::Migration[6.0]
def change
add_reference :reviews, :user, foreign_key: true
end
end
to be able to use seller: user you have to have this association in your Auction model like this:
belongs_to :seller, calss_name: 'User'
Also note you have to make sure that the seller_id column is present in your auctions table.
class Gallery < ApplicationRecord
belongs_to :artist
include Filterable
validates :user, presence: true
belongs_to :user, optional: true
resourcify
end
How would I be able to seed data that has multiple belongs_to?
Here is my method but it gives me an error of user cannot be blank
user = User.create! :name => 'Bobby Joe', :email => '20#gmail.com', :password => 'password', :password_confirmation => 'password'
artistOne = user.artists.create!(artist_name: 'ED', first_name: 'Edgar', last_name: 'Degas', email: 'edgardegas#yahoo.com', password: 'password', street: '2625 Ashcraft',city: 'San Diego',state: 'CA',zipcode: '92103',website: 'www.edgardegas.com',sales: '',phone: '(760)210-1326')
galleryOne = artistOne.galleries.create!(name: 'Exhibition of Art', website: 'www.ExhibitionOfArt.com', phone: '(619)264-8402', opening:'10:00:00', closing:'18:00:00', street:'325 15th Street', city:'San Diego', state:'CA', zipcode: '92101')
You need to add associations which you created (artistOne, user),
galleryOne = artistOne.galleries.create!(name: 'Exhibition of Art', website: 'www.ExhibitionOfArt.com', phone: '(619)264-8402', opening:'10:00:00', closing:'18:00:00', street:'325 15th Street', city:'San Diego', state:'CA', zipcode: '92101', artist: artistOne, user: user)
You have to set your relationship id in your Gallery creation like that :
galleryOne = artistOne.galleries.create!(name: 'Exhibition of Art', website: 'www.ExhibitionOfArt.com', phone: '(619)264-8402', opening:'10:00:00', closing:'18:00:00', street:'325 15th Street', city:'San Diego', state:'CA', zipcode: '92101', user_id: user.id, artist_id: artistOne.id)
I've ported a Rails app from Rails 3 to Rails 4 and most things work now, except for a problem with two levels of nested attributes:
I have ProductGroups, Variants and Prices.
Each ProductGroup has one or more variants. One of them is the master variant.
Each variant has many prices (one for each region).
I have a controller that updates ProductGroups. When the ProductGroup is updated, the master variant is updated at the same time. And prices in the master variant are also updated.
Here's a test that describes what's expected to happend:
test "should update master variant" do
login_as accounts(:johnny_admin)
p = ProductGroup.find product_groups(:toothbrush).id
assert_equal "10123", p.artno
assert_equal "10123", p.master_variant.artno
puts(p.master_variant.prices.to_a.to_s)
post :update,
id: product_groups(:toothbrush),
p: 'setup',
product_group: {
master_variant_attributes: {
artno: "20222",
supplier_artno: "1010",
prices_attributes: { "0": { price: "55", id: prices(:toothbrush_price_se).id } }
}
}
assert_response :redirect
assert_redirected_to edit_admin_product_group_path(p, :p => 'setup')
p = ProductGroup.find product_groups(:toothbrush).id
assert_equal "20222", p.artno
assert_equal "20222", p.master_variant.artno
assert_equal "1010", p.master_variant.supplier_artno
price = Prices.find prices(:toothbrush_price_se).id
assert_equal 55, price.price
end
But it fails with this error:
# Running:
.......[#<Price id: 510149407, variant_id: 630858089, region_id: 102782309, price: #<BigDecimal:55d2732f50a8,'0.95E2',9(18)>, created_at: "2016-12-30 11:14:28", updated_at: "2016-12-30 11:14:28">, #<Price id: 524805804, variant_id: 630858089, region_id: 960235695, price: #<BigDecimal:55d27339c510,'0.1E2',9(18)>, created_at: "2016-12-30 11:14:28", updated_at: "2016-12-30 11:14:28">]
E
Finished in 1.279989s, 6.2501 runs/s, 20.3127 assertions/s.
1) Error:
Admin::ProductGroupsControllerTest#test_should_update_master_variant:
ActiveRecord::RecordNotFound: Couldn't find Price with ID=510149407 for Variant with ID=
app/controllers/admin/product_groups_controller.rb:150:in `update'
test/functional/admin/product_groups_controller_test.rb:103:in `block in <class:ProductGroupsControllerTest>'
As you can see in the debug output, there is a price with ID 510149407 for that variant. And why is the ID of the variant empty?
I'm totally stuck.
Here's the permits for ProductGroup that I'm using:
def product_group_params
prices_attributes = { :prices_attributes => [ :id, :price ] }
master_variant_attributes = { :master_variant_attributes => [
:unit, :vat, :artno, :width, :height, :depth,
:description, :in_stock, :in_stock_verified_at,
:status, :supplier_id, :supplier_artno,
:alt_supplier_id, :alt_supplier_artno,
:supplier_price, :alt_supplier_price,
:supplier_reduction, :alt_supplier_reduction,
:supplier_carriage_percentage, :alt_supplier_carriage_percentage,
:our_expenses, :percentage_markup, :taric_code_id,
:reduction_group_id, :vendor_id, :vendor_artno, :is_expired,
:show_price, :reorder_point,
:place_of_storage_a, :place_of_storage_b, :place_of_storage_c,
prices_attributes
] }
params.require(:product_group).permit(:updated_by,
:title, :description, :license_code, :fixme,
master_variant_attributes,
:notes, :vat, :artno, :unit,
:width, :height, :depth, :in_stock, :published, :reorder_point,
:current_version, :changelog, :price_by_start_cost_and_per_unit,
:start_cost_variant_id, :unit_cost_variant_id,
:category_ids => [])
end
Here's how ProductGroup relates to the master variant:
has_one :master_variant,
-> { where(is_master: true, deleted_at: nil) },
:class_name => "Variant",
:foreign_key => 'product_group_id',
:dependent => :destroy,
:autosave => true
accepts_nested_attributes_for :master_variant
Here's how Variant relates to Prices:
has_many :prices, -> { order('region_id') }, :dependent => :destroy
accepts_nested_attributes_for :prices
I will gladly post any other excerpts from the code if it is of any help, but I'm not sure what could be of interest right now.
Any hints would be much appreciated!
I'm using postman to make post request to my rails/grape API
Here is the json object
{
"customer":{
"first_name":"Joe",
"last_name":"Doe",
"email":"test#test.com",
"phone":"999-999-9999",
"addresses_attributes":[{
"address":{
"address1":"123 somewhere st",
"customer_id":"",
"address2":"",
"city":"Moldor",
"state":"CA",
"zip":"99999",
"region_id":"1"
}
}]
}
}
If send this to a api/v1/customers.json
I get the following error message
"error": "first_name is missing, last_name is missing, email is missing, phone is missing",
If I change the JSON format to:
{
"first_name":"Joe",
"last_name":"Doe",
"email":"test#test.com",
"phone":"999-999-9999",
"addresses_attributes":[{
"address":{
"address1":"123 somewhere st",
"customer_id":"",
"address2":"",
"city":"Moldor",
"state":"CA",
"zip":"99999",
"region_id":"1"
}
}]
}
I does creates the customer but it does not creates the address
In my Models I have
#customer.br
has_many :addresses
accepts_nested_attributes_for :addresses, allow_destroy: true
#address.rb
belongs_to :customer
Here is the api/vi/curtomer.rb
desc "Create a Customer"
params do
requires :first_name, type: String, desc: "First Name"
requires :last_name, type: String, desc: "Last Name"
requires :email, type: String, desc: "Email"
requires :phone, type: String, desc: "Phone"
optional :notes, type: String, desc: "Notes"
end
post do
# Tried with new instead of create
# test = Customer.new({
# first_name: params[:first_name],
# last_name: params[:last_name],
# email: params[:email],
# phone: params[:phone],
# notes: params[:notes],
# addresses_attributes: params[:addresses]
# })
Customer.create({
first_name: params[:first_name],
last_name: params[:last_name],
email: params[:email],
phone: params[:phone],
notes: params[:notes]
# addresses_attributes: params[:addresses]
})
end
The address looks pretty much the same as the customers
I'm not using controllers per Grapes Documentation
EDIT: to add customer.rb create code
Think your json data should be:
{ "customer":
{
"first_name":"Joe",
"last_name":"Doe",
"email":"test#test.com",
"phone":"999-999-9999",
"addresses_attributes":[{
"address1":"123 somewhere st",
"customer_id":"",
"address2":"",
"city":"Moldor",
"state":"CA",
"zip":"99999",
"region_id":"1"
}]
}
}
Refer to this example.
If it not works, show your controller code.
Code
In my image model:
has_attached_file :pic
before_post_process :rename_pic
before_save ->{ p 'before_save ----------------' }
after_post_process ->{ p 'after_post_process --------------' }
def rename_pic
p 'en imagen'
p self
p 'en imagen'
end
In service that has many images:
# don't use accepts_nested_attributes_for
before_save :create_images
attr_accessor :images_attributes
def create_images
# images_attributes example value: { "0"=> {img_attrs}, "1" => {img_attrs1} }
images_attributes.all? do |k, image_attrs|
if image_attrs.delete(:_destroy) == "false"
p 'asd'
image = Image.new image_attrs.merge(service_id: id)
p image.service
p image.service_id
image.save
end
end
end
This is the output I get:
"asd"
"en imagen"
#<Image id: nil, service_id: nil, pic_file_name: "Screen_Shot_2013-04-07_at_5.18.03_PM.png", pic_content_type: "image/png", pic_file_size: 16041, pic_updated_at: "2013-07-30 22:58:46", created_at: nil, updated_at: nil, user_id: nil>
"en imagen"
G"after_post_process --------------"
#<Service id: 427, event_id: nil, min_capacity: nil, max_capacity: nil, price: #<BigDecimal:7fb6e9d73d48,'0.0',9(18)>, image_path: nil, name: "Super Franks", desc: "zxc", created_at: "2013-05-12 19:01:54", updated_at: "2013-07-30 19:32:48", address: "pasadena", longitude: 77.225, latitude: 28.6353, gmaps: true, city: "san francisco", state: "california", country_id: "472", tags: "Banquet", created_by: 22, avg_rating: #<BigDecimal:7fb6efdbcf10,'0.0',9(18)>, views: 27, zip_code: "", address2: "", price_unit: "", category_id: 3, featured: true, publish: true, slug: "banquet-super-franks", discount: nil, currency_code: "USD", video_url: "http://www.youtube.com/watch?v=A3pIrBZQJvE", short_description: "">
427
"before_save ----------------"
Problem
When calling
image = Image.new image_attrs.merge(service_id: id)
Paperclips seems to start processing, and then set service_id.
So when I try to use service inside rename_pic service is nil.
Any ideas on how to handle this?
This solved my problem, I changed:
before_post_process :rename_pic
to:
before_create :rename_pic
and this is rename_pic, for the record:
def rename_pic
extension = File.extname(pic_file_name).downcase
self.pic.instance_write :file_name,
"#{service.hyphenated_for_seo}#{extension}"
end
where service has_many images, and image belongs_to service.
Be carefull with the fix of #juanpastas, because if you change before_post_process to before_create, it will only run when you create your image, and not when you update it. To have the callback still run on update, do this:
class YourImage
has_attached_file :pic
# use both callbacks
before_create :rename_pic
before_post_process :rename_pic
def rename_pic
# assotiated_object is the association used to get pic_file_name
return if self.assotiated_object.nil?
extension = File.extname(pic_file_name).downcase
self.pic.instance_write :file_name,
"#{service.hyphenated_for_seo}#{extension}"
end
end