ruby on rails - references - Tipo de herencia de tabla única no válida: Rails
relationship rails 5 (4)
Recibo este error al intentar crear un nuevo Producto en mi aplicación Rails.
Tipo de herencia de tabla única no válida: la película no es una subclase de Producto
¿Cómo puedo resolver esto?
controlador
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
@products = Product.all
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
@product = Product.new
end
# GET /products/1/edit
def edit
end
# POST /products
# POST /products.json
def create
@product = Product.new(product_params)
respond_to do |format|
if @product.save
format.html { redirect_to @product, notice: ''Product was successfully created.'' }
format.json { render action: ''show'', status: :created, location: @product }
else
format.html { render action: ''new'' }
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if @product.update(product_params)
format.html { redirect_to @product, notice: ''Product was successfully updated.'' }
format.json { head :no_content }
else
format.html { render action: ''edit'' }
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
@product.destroy
respond_to do |format|
format.html { redirect_to products_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
@product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
params.require(:product).permit(:title, :artist, :type, :release_date, :category, :publisher, :format, :description, :sale_price, :rental_price)
end
end
migración
class CreateProducts < ActiveRecord::Migration
def change
create_table :products do |t|
t.string :title
t.string :artist
t.string :type
t.date :release_date
t.string :category
t.string :publisher
t.string :format
t.text :description
t.decimal :sale_price
t.decimal :rental_price
t.timestamps
end
end
end
Agregue self.inheritance_column = nil
a su modelo. tipo está reservado.
Otra forma es nombrar la columna de manera diferente ( product_type
estaría bien aquí) y agregar un atributo alias alias_attribute :type, :product_type
en la definición de su modelo.
De esta forma, puede usar @product.type
forma segura, porque Rails sustituirá a product_type
cuando lea o escriba en el atributo de type
.
Probado con Rails 4.1.2.
Si no tiene la intención de crear un modelo para su valor para ''tipo'', entonces lo que probablemente está sucediendo es ''tipo'' es una palabra reservada en ActiveRecord.
Ver http://en.wikibooks.org/wiki/Ruby_on_Rails/ActiveRecord/Naming
" type
- Esto solo se usa cuando tienes herencia de tabla única y debe contener un nombre de clase"
No debe usar la palabra clave type
como el nombre de la columna porque es una palabra reservada para ActiveRecord .
Pero si realmente desea usarlo, por cualquier motivo (como si no tuviera control sobre la estructura de la base de datos), esto es lo que debe hacer:
Primero, asegúrese de que su modelo de película herede del modelo (abstracto) "abstracto" Producto:
class Product < ActiveRecord::Base
TYPES = %w( Movie )
before_save :set_type
validates :type, presence: true, :inclusion => { :in => TYPES }
def set_type
raiser "You must override this method in each model inheriting from Product!"
end
# ...
class Movie < Product
def set_type # If you don''t implement this method, an error will be raised
self.type = ''Movie''
end
Y luego en su ProductsController puede administrar (CRUD) todo tipo de productos.
Para agregar un nuevo tipo de producto: solo tiene que definir un nuevo Modelo que hereda del Producto, implementar su método set_type y agregar el tipo en la Constante del producto:
class Book < Product
def set_type
self.type = ''Book''
end
#...
class Product < ActiveRecord::Base
TYPES = %w( Movie Book )