Polymorphic association undefined method `build_product' - ruby-on-rails

I am struggling to see what I am doing wrong here..
I have an order model which needs to be able to hold one product, the product needs to be polymorphic.
I have a product/model called orthosis_specification and for some reason I am getting this error when I use it in a fields_for creation.
Migration -
class CreateOrders < ActiveRecord::Migration
def change
create_table :orders do |t|
t.datetime :order_date
t.datetime :date_required
t.boolean :correct
t.references :user, index: true, foreign_key: true
t.references :practitioner, index: true, foreign_key: true
t.references :product, polymorphic: true
t.references :shipping_address, index: true, foreign_key: true
t.references :invoice_address, index: true, foreign_key: true
t.timestamps null: false
end
end
end
Order Controller -
def new
#order = Order.new
#order.build_patient
#order.build_product #Also tried: #order.build_orthosis_specification
end
Order Model -
class Order < ActiveRecord::Base
has_one :patient
belongs_to :product, polymorphic: true
accepts_nested_attributes_for :patient,
reject_if: proc { |attributes| attributes['first_name'].blank? },
allow_destroy: true
accepts_nested_attributes_for :product,
reject_if: proc { |attributes| attributes['transfer_name'].blank? },
allow_destroy: true
def to_s
name
end
end
Orthosis Specification Model -
class OrthosisSpecification < ActiveRecord::Base
has_one :order, :as => :product, class_name: 'Order'
end
Order View -
<%= form_for(#order) do |f| %>
<% if #order.errors.any? %>
<% end %>
<%= f.fields_for :orthosis_specification do |fa| %>
Actual error message -
undefined method `build_orthosis_specification' for #<Order:0x007f8950e29970>
Orthosis Specification Migration -
class CreateOrthosisSpecifications < ActiveRecord::Migration
def change
create_table :orthosis_specifications do |t|
t.string :transfer_name
t.string :modifications
t.string :primary_mods
t.string :top_opening
t.string :side_opening
t.string :chape_position
t.string :scan_file
end
end
end
Any help would be massively appreciated, thanks!

Polymorphic associations don't generate the build_xxx methods. You can create a new product only if you know what kind of product you want to create :
#Creating a new OrthosisSpecification product associated with #order :
#order.product = OrthosisSpecification.new
Documentation : http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

Related

Building Rails Forms for saving Polymorphic Associations

I have categories model which I would like to be able to use with different models. That's how I ended up using Polymorphic with has_many.
With Rails_admin everything works without a problem. But, when I want to create a form by myself, I can't seem to make it save. Here is what I have:
category.rb
class Category < ActiveRecord::Base
has_many :categorizings, inverse_of: :category, dependent: :destroy
has_many :cars, through: :categorizings, :source => :categorizable,
:source_type => 'Car'
end
categorizing.rb
class Categorizing < ActiveRecord::Base
belongs_to :category
belongs_to :categorizable, :polymorphic => true
end
car.rb
class Car < ActiveRecord::Base
has_many :categorizings, :as => :categorizable, inverse_of: :car, dependent: :destroy
has_many :categories, through: :categorizings
end
vendor.rb
class Vendor < ActiveRecord::Base
has_many :categorizings, :as => :categorizable, inverse_of: :vendor, dependent: :destroy
has_many :categories, through: :categorizings
end
cars_controller.rb
class CarsController < ApplicationController
def new
#car = Car.new
end
def create
#car = current_user.cars.build(car_params)
if #car.save
redirect_to #car
else
render 'new'
end
end
private
def car_params
params.require(:car).permit(:name, :details, :type, :category_ids => [] )
end
end
schema.rb
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "categorizings", force: :cascade do |t|
t.integer "category_id"
t.integer "categorizable_id"
t.string "categorizable_type"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "categorizings", ["categorizable_type", "categorizable_id"], name: "index_categorizings_on_categorizable_type_and_categorizable_id", using: :btree
This is what I have in the form
<%= f.collection_select :category_ids, Category.all, :id, :name %>
And I receive this error:
Unpermitted parameter: category_ids
I am very confused right now and lost in models. Dont know this is the best approach or not. I would be glad if someone could tell me where I do the mistake.
Using this select_tag solved my problem
<%= f.select :category_ids, Category.all.collect {|x| [x.name, x.id]}, {}, :multiple => true %>
but stops working if I disable multiple like
:multiple => false

Rating with Rails (many_to_many)

I'm trying to build a rating system into my app and currently stuck on the associations and indices. I'm quite new to this so I need all the help I can get...
User model
class User < ActiveRecord::Base
has_many :demos
has_many :ratings
has_many :reviewed, through: :ratings, source: :reviewed'Demo'
That's part of it.
Demo model
class Demo < ActiveRecord::Base
belongs_to :user
belongs_to :subject
has_many :ratings
has_many :reviewers, through: :ratings, source: :reviewer
The subject is irrelevant.
Rating model
class Rating < ActiveRecord::Base
belongs_to :reviewed
belongs_to :reviewer
validates :rating, presence: true, numericality: { :greater_than_or_equal_to => 0, :less_than_or_equal_to => 5}
end
end
And now you can tell I'm not really sure what I'm doing.
Ratings Migration Table
class CreateRatings < ActiveRecord::Migration
def change
create_table :ratings do |t|
t.float :rating, default: 2.5
t.belongs_to :reviewed, index: true
t.belongs_to :reviewer, index: true
t.timestamps null: false
end
end
end
Demos Migration Table
class CreateDemos < ActiveRecord::Migration
def change
create_table :demos do |t|
t.references :user, index: true
t.references :subject, index: true
t.string :name
t.text :content
t.string :materials
t.timestamps null: false
end
add_index :demos, [:user_id, :subject_id, :created_at]
end
end
I haven't built a controller for ratings yet since I'm just testing the relationships using the sandbox console.
I've successfully created a Rating, but #user.reviewed and #user.ratings returns a blank array in the Active Record even though #rating has all the Demo and User ids.

How to add more that one belongs_to to same table in rails

Hi I have student table in Rails
class CreateStudents < ActiveRecord::Migration
def change
create_table :students do |t|
t.belongs_to :school, index: true, foreign_key: true,null: false
t.belongs_to :user, index: true, foreign_key: true,null: false
t.belongs_to :division, index: true, foreign_key: true,null: false
t.belongs_to :section, index: true, foreign_key: true,null: false
t.timestamps null: false
end
end
end
, Now I want to add two foriegn key into that table
1st father , where father belongs to user table and in DB its role save is father
2nd mother , where mother belongs to user table and in DB its role save is mother
I am new to rails and try this
t.belongs_to :user, index: true,foreign_key: 'father_id',null: false
but it did not create father_id in student table
I want to access father like student.father. Please help me to do this
What you're looking at is a self referential join:
#db/migrate/create_parents____.rb
class CreateParents < ActiveRecord::Migration
def change
change_table :students do |t|
t.references :father, index: true, null: false
t.references :mother, index: true, null: false
end
end
end
#app/models/user.rb
class User < ActiveRecord::Base
belongs_to :father, class_name: "User"
belongs_to :mother, class_name: "User"
end

Rails: Self joins

I'm trying design a model which has relation to itself
Model:
class Department < ActiveRecord::Base
belongs_to :organization
has_many :positions
has_many :sub_departments, class: 'Department', foreign_key: 'parent_id'
end
Migration:
class CreateDepartments < ActiveRecord::Migration
def change
create_table :departments do |t|
t.string :name
t.references :parent, index: true
t.references :organization, index: true
t.timestamps
end
end
end
When I call Department.first.sub_departments I get an error: NoMethodError: undefined method 'relation_delegate_class' for "Department":String. What am I doing wrong?
Thanks!
I think you should use class_name: instead of class:.

Unknown primary key for table

I'm making an extension for refinerycms in rails and this is the structure I follow :
Project has many project_images
Project_images belongs_to Project & Image ( The refinery Image class )
Now when I want to create a new object of ProjectImage in my Project class I always get this error :
Unknown primary key for table refinery_projects_images in model Refinery::Projects::ProjectImage.
I don't need a primary key for this table because it is a join table. Here is the code of my models and migration file:
Migration.rb
class CreateProjectsProjects < ActiveRecord::Migration
def up
create_table :refinery_projects do |t|
t.string :title
t.text :description
t.string :investor
t.string :location
t.string :area
t.string :purpose
t.string :architect
t.string :users
t.integer :position
t.integer :position
t.timestamps
end
add_index :refinery_projects, :id
create_table :refinery_projects_images, :id => false do |t|
t.references :image
t.references :project
t.integer :position
t.string :category
t.string :caption
end
add_index :refinery_projects_images, [:image_id, :project_id], :uniq => true
end
def down
if defined?(::Refinery::UserPlugin)
::Refinery::UserPlugin.destroy_all({:name => "refinerycms-projects"})
end
if defined?(::Refinery::Page)
::Refinery::Page.delete_all({:link_url => "/projects/projects"})
end
drop_table :refinery_projects
drop_table :refinery_projects_images
end
end
Project.rb
module Refinery
module Projects
class Project < Refinery::Core::BaseModel
self.table_name = 'refinery_projects'
attr_accessible :title, :description, :investor, :location, :area, :purpose, :architect, :users, :position, :position, :images_attributes
acts_as_indexed :fields => [:title, :description, :investor, :location, :area, :purpose, :architect, :users]
validates :title, :presence => true, :uniqueness => true
has_many :project_images
has_many :images, :through => :project_images, :order => 'position ASC'
accepts_nested_attributes_for :images, :allow_destroy => false
def images_attributes=(data)
ProjectImage.delete_all(:project_id => self.id)
(0..(data.length-1)).each do |i|
unless (image_data = data[i.to_s]).nil? or image_data['id'].blank?
project_image = self.project_images.new(:image_id => image_data['id'].to_i, :position => i)
# Add caption if supported
if false
project_image.caption = image_data['caption']
end
self.project_images << project_image
end
end
end
end
end
end
ProjectImage.rb
module Refinery
module Projects
class ProjectImage < Refinery::Core::BaseModel
self.table_name = 'refinery_projects_images'
attr_accessible :image_id, :position
belongs_to :image, :class_name => 'Refinery::Image'
belongs_to :project, :class_name => 'Refinery::Projects::Project'
end
end
end
Somebody knows why he keeps looking for the primary key?
Refinery::Core::BaseModel is somehow derived from ActiveRecord::Base. When you use that class then your table layout needs an id. If you don't want an id, Have a look at has_and_belongs_to_many in the rails guides: http://guides.rubyonrails.org/association_basics.html

Resources