Rails 3.1, Ruby 1.87 (don't hate me). I watched the Railscasts on Nested Forms; I only put that in so you can point out where I might have missed something in the Railscasts if you know them.
Note: I added #sample_data_set.build_sample_data_template but got "unknown attribute: sample_data_set_id" on the post instead [the code is also posted with the new below).
Using a Nested form on Create/New; hit Submit and get:
ActiveRecord::UnknownAttributeError (unknown attribute:
sample_data_templates):
app/controllers/sample_data_sets_controller.rb:50:in new'
app/controllers/sample_data_sets_controller.rb:50:increate'
Sample Data Set Model:
class SampleDataSet < ActiveRecord::Base
has_one :sample_data_template, :dependent => :destroy
accepts_nested_attributes_for :sample_data_template
end
Sample Data Template Model:
class SampleDataTemplate < ActiveRecord::Base
belongs_to :sample_data_set
#Random info generation
def self.name_gen(*prepend)
character_map = [('a'..'z'),('A'..'Z')].map{|i| i.to_a}.flatten
name = (0..8).map{ character_map[rand(character_map.length)] }.join
if prepend[0].nil? || prepend[0] == ""
return name
else
return prepend[0].to_s + "_" + name
end
end
def self.ssn_gen
#broke this out as its own method in case someone wants some logic later one
ssn = ""
3.times do
ssn = ssn + (100..999).to_a.choice.to_s
end
return ssn
end
def self.row_gen(row_count)
#data_rows = Array.new
i = 0
until i > row_count do
#row = SampleDataSet.first
#row.officialFirstName = SampleDataTemplate.name_gen
#row.officialLastName = SampleDataTemplate.name_gen
#row.emailAddresses = #row.officialFirstName + #row.officialLastName + "#aaa.aaa.edu"
#row.ssn = SampleDataTemplate.ssn_gen
#data_rows << #row
i += 1
end
return #data_rows
end
end
Sample Data Controller#New
def new
#sample_data_set = SampleDataSet.new
#sample_data_set.build_sample_data_template #after adding this I get error:unknown attribute: sample_data_set_id
respond_to do |format|
format.html # new.html.erb
format.json { render :json => #sample_data_set }
end
Sample Data Controller#Create
def create
#sample_data_set = SampleDataSet.new(params[:sample_data_set])
respond_to do |format|
if #sample_data_set.save
format.html { redirect_to #sample_data_set, :notice => 'Sample data set was successfully created.' }
format.json { render :json => #sample_data_set, :status => :created, :location => #sample_data_set }
else
format.html { render :action => "new" }
format.json { render :json => #sample_data_set.errors, :status => :unprocessable_entity }
end
end
end
end
Update, added form piece
<div class="sample_fields">
<%= f.fields_for :sample_data_templates do |builder| %>
<%= render "sample_data", :f => builder%>
<% end %>
</div>
Update, Schema:
ActiveRecord::Schema.define(:version => 20120103172936) do
create_table "sample_data_sets", :force => true do |t|
t.string "title"
t.text "description"
t.string "created_for"
t.string "created_by"
t.integer "number_of_records"
t.integer "sample_data_template_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "sample_data_templates", :force => true do |t|
t.integer "sample_data_set_id"
t.string "irn"
t.string "ssn"
t.string "officialLastName"
t.string "officialFirstName"
t.string "emailAddresses"
t.string "campusNum"
t.string "internationalId"
t.string "internationalIdCountry"
t.string "gender"
t.string "officialMiddleInitial"
t.string "previousLastName"
t.string "previousFirstName"
t.string "previousMiddleInitial"
t.string "addressLine1"
t.string "addressLine2"
t.string "addressLine3"
t.string "city"
t.string "state"
t.string "zipCode"
t.string "province"
t.string "homeAreaCode"
t.string "homePhoneNumber"
t.string "homePhoneExtenstion"
t.string "homePhoneCountryCode"
t.string "workAreaCode"
t.string "workPhoneNumber"
t.string "workExtenstion"
t.string "workPhoneCountryCode"
t.string "faxAreaCode"
t.string "faxPhoneNumber"
t.string "faxExtension"
t.string "faxCountryCode"
t.string "race"
t.string "previousDegree"
t.string "region"
t.string "foreignTranscript"
t.string "apolloEmployee"
t.string "nursingLicenseExpiration"
t.string "nursingInsuranceExpiration"
t.string "otherInsuranceExpiration"
t.string "program"
t.string "version"
t.string "groupId"
t.string "team"
t.string "enrollmentUserId"
t.string "admissionsUserId"
t.string "oldProgram"
t.string "oldVersion"
t.string "galaxyStudentOid"
t.string "suffixOne"
t.string "suffixTwo"
t.string "employeId"
t.string "promoCode"
t.string "revCampusOid"
t.string "FerpaNotes"
t.string "isWavierHigh"
t.string "executingUserId"
t.string "totalDeclaredExtCredits"
t.datetime "insuranceExpireDate"
t.datetime "acknowledgementDate"
t.datetime "scheduledReentryDate"
t.datetime "scheduledStartDate"
t.datetime "dateOfBirth"
t.datetime "enrollAgreeSignDate"
t.boolean "usCitizen"
t.boolean "financialAid"
t.boolean "overrideFlag"
t.datetime "created_at"
t.datetime "updated_at"
end
end
Does sample_data_templates table have a sample_data_set_id column? Perhaps you didn't add it to the migration or did not run the migration?
Related
I have 2 models: Customer and Sale
class Sale < ApplicationRecord
belongs_to :customer, inverse_of: :sales
accepts_nested_attributes_for :customer
end
class Customer < ApplicationRecord
has_many :sales, inverse_of: :customer
end
In SALE controller i have a form with CUSTOMER'S values
To create new sale i don't have any problem, but when i try update, the error "unknown attribute 'valor_oferta' for Customer" appears
Sale Controller
class SalesController < ApplicationController
before_action :authenticate_user!
def new
#sale = Sale.new
#sale.build_customer
end
def create
#sale = Sale.new(proposta_params)
respond_to do |format|
if #sale.save
format.html { redirect_to dashboard_path, notice: 'Proposta criada com sucesso.' }
else
format.html { render :new }
#sale.errors.each do |erro|
puts erro
end
end
end
end
def edit
#sale = Sale.find(params[:id])
#sale.customer
end
def update
#sale = Sale.find(params[:id])
respond_to do |format|
if #sale.customer.update(proposta_params)
format.html { redirect_to dashboard_path, notice: 'Proposta alterada com sucesso.' }
else
format.html { render :edit }
#sale.errors.each do |erro|
puts erro
end
end
end
end
private
def proposta_params
params.require(:sale).permit(:valor_oferta, :grupo_promocao, :codigo_oferta, :modo_pagamento, :vencimento, :banco, :agencia, :conta, :isento, :valor, :data_envio_qualidade, :data_agendamento_qualidade, :janela_agendamento, :data_instalacao_qualidade,:tv_id, :phone_id, :internet_id, :equipamentos, :cep, :rua, :numero, :complemento, :bairro, :cidade, :uf, :ponto_de_referencia, :obs, customer_attributes: [:name, :cpf_pf, :nascimento_pf, :nome_mae_pf, :nome_mae_pf, :cnpj_pj, :fundacao_pj, :telefone1, :telefone2, :telefone3, :email, :juridica])
end
end
I already tried use only
if #sale.update(proposta_params)
but in this case, another Customer is created and not updated
I use Rails 5
#################EDIT
db/schema.rb
create_table "sales", force: :cascade do |t|
t.integer "lead_id"
t.string "solicitante"
t.integer "protocolo"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "tv_id"
t.integer "phone_id"
t.integer "internet_id"
t.string "solicitante_pf"
t.string "valor_oferta"
t.string "grupo_promocao"
t.string "codigo_oferta"
t.string "vencimento"
t.boolean "isento"
t.string "valor"
t.string "data_envio_qualidade"
t.string "data_agendamento_qualidade"
t.string "janela_agendamento"
t.string "data_instalacao_qualidade"
t.integer "customer_id"
t.string "agencia"
t.string "conta"
t.string "banco"
t.string "modo_pagamento"
t.integer "equipamentos"
t.string "cep"
t.string "rua"
t.string "numero"
t.string "complemento"
t.string "bairro"
t.string "cidade"
t.string "uf"
t.string "ponto_de_referencia"
t.text "obs"
t.integer "user_id"
t.integer "user_qualidade_id"
t.integer "status_sale_id"
t.index ["customer_id"], name: "index_sales_on_customer_id", using: :btree
t.index ["internet_id"], name: "index_sales_on_internet_id", using: :btree
t.index ["lead_id"], name: "index_sales_on_lead_id", using: :btree
t.index ["phone_id"], name: "index_sales_on_phone_id", using: :btree
t.index ["status_sale_id"], name: "index_sales_on_status_sale_id", using: :btree
t.index ["tv_id"], name: "index_sales_on_tv_id", using: :btree
t.index ["user_id"], name: "index_sales_on_user_id", using: :btree
end
Paperclip::Error in ModificationsController#create Modification model missing required attr_accessor for 'image_file_name'
Error:
Model: modification.rb
class Modification < ActiveRecord::Base
has_attached_file :image,
styles: { thumb: ["64x64#", :jpg],
original: ['500x500>', :jpg] },
convert_options: { thumb: "-quality 75 -strip",
original: "-quality 85 -strip" }
validates_attachment :image,
content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] }
end
Controller: modifications_controller.rb
class ModificationsController < ApplicationController
def index
#modifications = Modification.order('created_at')
end
def new
#modifications = Modification.new
end
def create
#modifications = Modification.new(modification_params)
if #modifications.save
flash[:success] = "Modification contributed!"
redirect_to collection_path
else
render 'new'
end
end
private
def modification_params
params.require(:modification).permit(:image, :title)
end
end
Migration: _create_modifications.rb
class CreateModifications < ActiveRecord::Migration
def change
create_table :modifications do |t|
t.string :title
t.string :image_file_name
t.string :image_content_type
t.integer :image_file_size
t.timestamps null: false
end
end
end
Migration: _add_attachment_modification_to_profiles.rb
class AddAttachmentModificationToProfiles < ActiveRecord::Migration
def self.up
change_table :profiles do |t|
t.attachment :modification
end
end
def self.down
remove_attachment :profiles, :modification
end
end
Schema.rb
create_table "modifications", force: :cascade do |t|
t.string "title"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
...
create_table "profiles", force: :cascade do |t|
t.integer "user_id"
t.string "first_name"
t.string "last_name"
t.string "location"
t.string "modifications"
t.string "website"
t.text "bio"
t.datetime "created_at"
t.datetime "updated_at"
t.string "avatar_file_name"
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
t.string "modification_file_name"
t.string "modification_content_type"
t.integer "modification_file_size"
t.datetime "modification_updated_at"
end
You declared twice has_attached_file :image method in your Model: modification.rb
Try to delete very first one has_attached_file :image and let me know if that works for you.
My problem is similar to:
My cloning method is stealing the children from the original model
But I can't seem to get the solution for this to work with mine. I'm trying to create an order exchange form which involves populating the form with the old record details. So when I save the form it creates a new Order record but the children seem to get deleted from the old Order record and siphoned into the new one.
Here's the code:
def new
#old_order = Order.includes(:line_items).find(params[:id])
#order = Order.new #old_order.attributes
#order.line_items = []
#old_order.line_items.each do |old|
new = old.dup # the line_item id is set before creation.
new.order_id = #order.id
new.save!
#order.line_items << new
#old_order.line_items << old # this was to see if the old line_items would reappend to the old order. Didn't help...
end
end
def create
#order = Order.new(exchange_order_params)
if #order.save
#order.update_attributes!(stage: 2, ordered_at: Date.today)
redirect_to admin_returns_url, notice: "Order moved to 'accepted' for processing"
else
flash.now[:alert] = "Please try again"
render :action => "new"
end
end
private
def exchange_order_params
params.require(:order).permit(:id, :user_id,
line_items_attributes: [:id, :order_id, :cart_id, :quantity, :_destroy,
product_attributes: [:id, :sku, :euro_price, :sterling_price, :product_group_id, :product_size_id, :product_waistband_id]])
end
Schema.rb
create_table "orders", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "returned", default: false
t.date "date_sent"
t.date "ordered_at"
t.integer "user_id"
t.boolean "return_requested", default: false
t.integer "stage", default: 0
t.decimal "order_total", default: 0.0
t.string "transaction_secret"
t.string "token"
t.string "uuid"
t.string "currency"
t.float "discounted_by", default: 0.0
end
add_index "line_items", ["cart_id"], name: "index_line_items_on_cart_id", using: :btree
add_index "line_items", ["order_id"], name: "index_line_items_on_order_id", using: :btree
add_index "line_items", ["product_id"], name: "index_line_items_on_product_id", using: :btree
create_table "line_items", force: :cascade do |t|
t.integer "quantity"
t.integer "order_id"
t.integer "cart_id"
t.integer "product_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.float "unit_price"
t.string "currency"
end
create_table "product_groups", force: :cascade do |t|
t.string "name"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "product_sizes", force: :cascade do |t|
t.string "specification"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "product_waistbands", force: :cascade do |t|
t.string "specification"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "products", force: :cascade do |t|
t.integer "sku"
t.integer "product_group_id"
t.integer "product_size_id"
t.integer "product_waistband_id"
t.decimal "euro_price"
t.decimal "sterling_price"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "stock_level", default: 0
end
add_index "products", ["product_group_id"], name: "index_products_on_product_group_id", using: :btree
add_index "products", ["product_size_id"], name: "index_products_on_product_size_id", using: :btree
add_index "products", ["product_waistband_id"], name: "index_products_on_product_waistband_id", using: :btree
Also in the Order model I am randomising the id before_create so that when the user submits the form, it creates a dupe copy with a different Order id. This is the same for LineItems.
Order.rb (same in LineItem.rb)
before_create :randomize_id
private
def randomize_id
begin
self.id = SecureRandom.random_number(1_000_000)
end while Order.where(id: self.id).exists?
end
My approach would be to override the ActiveRecord::Base#dup method in the Order model so that it's recursive, meaning that it also duplicates the LineItem collection:
class Order < ActiveRecord::Base
def dup
duped_order = super
duped_order.line_items = line_items.map(&:dup)
duped_order
end
end
doing it this way makes it easily testable. Now the controller becomes:
class OrderController < ApplicationController
def new
#order = Order.find(params[:id]).dup
end
def create
# not sure how your form populates the params hash
# here you need to new-up and then save the order and the line items
# with the attributes from the form
end
end
Do write tests to confirm that this is doing what you intend. This is the perfect example of where the old "fat model skinny controller" paradigm should be applied.
I am having trouble trying to achieve the following, mostly in the controller part:
I have a User model and a Firm model.
A User can create a Firm, this will mean that this user will be the firm owner. Additionally, this user can add other users to join the firm.
So far, my Models are as follows:
class Firm< ActiveRecord::Base
has_many :users, dependent: :destroy
end
class User < ActiveRecord::Base
...
belongs_to :bufete
end
Here is my create action in my firms controller:
def create
#bufete = Bufete.create(bufete_params)
#user = current_user
#bufete.users.create(#user) # Mark that this user belongs to a bufete
#user.owner = true # Mark this user as the owner of the Bufete
respond_to do |format|
if #bufete.save && #user.save
format.html { redirect_to #bufete, :flash => { :success => 'Tu bufete ha sido creado exitosamente.' } }
format.json { render :show, status: :created, location: #bufete }
else
format.html { render 'new', :flash => { :danger => 'Hubo un error al tratar de crear tu bufete.
Porfavor asegurese de que el correo electronico es una direccion valida' } }
format.json { render json: #bufete.errors, status: :unprocessable_entity }
end
end
end
Schema.rb file:
ActiveRecord::Schema.define(version: 20150730061404) do
create_table "bufetes", force: :cascade do |t|
t.string "name"
t.string "address"
t.string "telephone"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "description"
t.string "code"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "admin", default: false
t.boolean "premium", default: false
t.integer "bufete_id"
t.string "name"
t.string "last_name"
t.boolean "owner", default: false
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
I believe my associations are correct, but I could be mistaken. My main problem is in the controller. When a user creates a firm, how do I assign this user to be the owner of this Firm? At the same time how do I add this user to the Firm.users collection?
Also, how would I go for adding future users to a specific firm's users collection?
Important: A user can only create ONE Firm. At the same time, a user can only belong to ONE firm as well. If a user creates a firm, it will belong to THAT firm.
I assume Bufete is equal to Firm model, in the code below I'll use Bufete instead of Firm. You can check whether the user can create a new Bufete before creating the Bufete record.
def create
#user = current_user
if #user.can_create_bufete?
#bufete = Bufete.create(bufete_params)
# assign user to #bufete instead of #bufete.users.create()
#user.bufete = #bufete
#user.owner = true
# add your response_to block for #user.saved
else
# add your response_to block of not creating new Bufete
end
end
Then you'll check whether the user can create a Bufete object or not in your User model.
def can_create_bufete?
!owner && !bufete.present? # or any condition that meets your requirement
end
i have two objects
- material
- lesson
each material can have and belong to lesson; each lesson can have and belong to material.
in material_controller when i try to create
#material = Material.new(params[:material])
class Material < ActiveRecord::Base
has_and_belongs_to_many :lessons
attr_accessible :content_type, :user_id, :lesson_ids
here is params
"material"=>{"content_type"=>"2",
"detail_content"=>"",
"user_id"=>"5",
"lesson_ids"=>"[]"},
create_table "lessons", :force => true do |t|
t.string "title"
t.string "description"
t.integer "course_id"
t.integer "sequence"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "lessons_materials", :force => true do |t|
t.integer "lesson_id"
t.integer "material_id"
end
create_table "materials", :force => true do |t|
t.integer "content_type"
t.text "detail_content"
t.text "embedded_content"
t.string "stored_file_name"
t.string "stored_content_type"
t.integer "stored_file_size"
t.datetime "stored_updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "user_id"
end
I think your lesson_ids param should be nil when you have no lesson associated, instead of being an array.