How to use the 'ranked-model' gem with MTI? - ruby-on-rails

I want to use the 'ranked-model' gem with Multiple Table Inheritance.
My use case looks like this:
class MitarbeiterListeEintrag < ActiveRecord::Base
end
class Mitarbeiter < MitarbeiterListeEintrag
set_table_name "mitarbeiter"
end
class MitarbeiterTrenner < MitarbeiterListeEintrag
set_table_name "mitarbeiter_trenner"
end
class CreateMitarbeiter < ActiveRecord::Migration
def change
create_table :mitarbeiter do |t|
t.references :team, null: false
t.string :vorname, null: false
t.string :nachname, null: false
t.string :geburtsdatum, null: false
t.integer :sort_order, null: false
end
end
end
class CreateMitarbeiterTrenner < ActiveRecord::Migration
def change
create_table :mitarbeiter_trenner do |t|
t.references :team, null: false
t.string :name, null: false
t.integer :sort_order, null: false
end
end
end
Mitarbeiter and MitarbeiterTrenner are two different tables but they share the sort order as they are displayed in the same list.

To use the 'ranked-model' gem I need to add the following to the MitarbeiterListeEintrag model:
class MitarbeiterListeEintrag < ActiveRecord::Base
include RankedModel
ranks :sort_order
end

Related

ActiveModel::UnknownAttributeError (unknown attribute 'product_id' for Property.):

So I am struggling with this error. While building a react on rails project.
Completed 500 Internal Server Error in 75ms (ActiveRecord: 6.1ms)
ActiveModel::UnknownAttributeError (unknown attribute 'product_id' for >Property.):
When I run this controller:
class SendDataController < ApplicationController
protect_from_forgery with: :null_session
def save
product = Product.create(name:params[:name], upc:params[:upc].to_i, available_on:params[:availableon])
property = product.Properties.build(name:params[:properties][0][:name])
property.save
end
end
I have tried to things found here and here. But I am getting no where. Below is my current setup.
Models:
class ProductProperty < ApplicationRecord
belongs_to :Property
belongs_to :Product
end
class Product < ApplicationRecord
has_many :Properties
has_many :ProductProperties
end
class Property < ApplicationRecord
belongs_to :Product
has_one :ProductProperty
end
Migration:
class CreateProducts < ActiveRecord::Migration[5.2]
def change
create_table :products do |t|
t.string :name
t.string :upc
t.datetime :available_on
t.timestamps
end
end
end
class CreateProperties < ActiveRecord::Migration[5.2]
def change
create_table :properties do |t|
t.string :name
t.timestamps
end
end
end
class CreateProductProperties < ActiveRecord::Migration[5.2]
def change
create_table :product_properties do |t|
t.string :value
t.timestamps
end
end
end
class AddProductRefToProperties < ActiveRecord::Migration[5.2]
def change
add_reference :properties, :Product, foreign_key: true
end
end
class AddProductRefToProductProperties < ActiveRecord::Migration[5.2]
def change
add_reference :product_properties, :Product, foreign_key: true
end
end
class AddPropertiesRefToProductProperties < ActiveRecord::Migration[5.2]
def change
add_reference :product_properties, :Property, foreign_key: true
end
end
Schema:
ActiveRecord::Schema.define(version: 2018_09_24_163027) do
create_table "product_properties", force: :cascade do |t|
t.string "value"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "Product_id"
t.integer "Property_id"
t.index ["Product_id"], name: "index_product_properties_on_Product_id"
t.index ["Property_id"], name: "index_product_properties_on_Property_id"
end
create_table "products", force: :cascade do |t|
t.string "name"
t.string "upc"
t.datetime "available_on"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "properties", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "Product_id"
t.index ["Product_id"], name: "index_properties_on_Product_id"
end
end
Thanks for any help you can give me!
ActiveModel::UnknownAttributeError (unknown attribute 'product_id' for
Property.)
It says there is no product_id in properties table. That is true because you have Product_id instead of product_id, so is the error.
Rails Conventions
By default, attribute names should be snakecase. You should generate a migration which will change Product_id to product_id and migrate as to fix the error. You should also change association names to snakecase as well. For instance
belongs_to :Property
belongs_to :Product
should be
belongs_to :property
belongs_to :product

Association between two STI/Polymorphic

Currently I have a Group and GroupPeriod that contains the same attributes
create_table "groups", force: :cascade do |t|
t.bigint "company_id"
t.string "name"
t.date "cutoff_date"
t.date "processing_date"
t.integer "working_days"
t.integer "working_hours"
t.integer "status"
t.float "basic_pay"
t.string "type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["company_id"], name: "index_groups_on_company_id"
end
create_table "group_periods", force: :cascade do |t|
t.bigint "company_id"
t.date "start_date"
t.date "end_date"
t.string "type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "group_id"
t.index ["company_id"], name: "index_group_periods_on_company_id"
t.index ["group_id"], name: "index_group_periods_on_group_id"
end
The logic is Group has many GroupPeriods. But then I have different groups; Bill and Pay. So I'm creating an STI for both BillGroup and PayGroup:
class Group < ApplicationRecord
has_many :group_periods
end
class BillGroup < Group
#=> has_many :bill_periods??
end
class PayGroup < Group
#=> has_many :pay_periods??
end
The issue I'm having is that each group will have many PayPeriod or BillPeriod. So I created a GroupPeriod to link
class GroupPeriod < ApplicationRecord
belongs_to :group
end
class BillPeriod < GroupPeriod
#=> belongs_to :bill_group??
end
class PayPeriod < GroupPeriod
#=> belongs_to :pay_group??
end
My question is, how can I ensure through inheritance, I can be flexible that
BillGroup has many BillPeriods;
PayGroup has many PayPeriods;
without overlapping (BillGroup will not see PayPeriod and vice versa) with each other? At the same time, is this a bad practice that I should make them into 2 different tables for each BillGroup and PayGroup?
class Group < ApplicationRecord
has_many :group_periods
end
class Period < ApplicationRecord
belongs_to :group
belongs_to :group_periods, polymorphic: true
end
class BillPeriod < GroupPeriod
has_many :periods, as: :group_periods, dependent: :destroy
end
class PayPeriod < GroupPeriod
has_many :periods, as: :group_periods, dependent: :destroy
end
your model looks something like this , rest depends on your associations.

Undefined method `set_primary_key' for Client

I have a problem with using Class-Table-Inheritance gem. When I try check in console the correctness of inheritance console return this error:
NoMethodError: undefined method `set_primary_key' for Client (call
'Client.connection' to establish a connection):Class
I define primary key for Client, but there is still error.
class Person < ActiveRecord::Base
acts_as_superclass
self.table_name = 'people'
end
Model Client
class Client < ActiveRecord::Base
inherits_from :person
self.primary_key = "person_id"
end
Part of migration file CreatePeople
create_table :people do |t|
t.string :pesel, null: false
t.string :first_name, null: false
t.string :last_name, null: false
t.string :email, null: false
t.date :date_of_birth, null: false
t.timestamps null: false
end
Part of migration file CreateClients
create_table :clients, :inherits => :person do |t|
end
How to resolve this problem?

Relationships with different name than the standard on ActiveRecord migrations

I have generated three models (rails generate model): Professionals, ProfessionalCouncils and States. The Professionals table must have a reference to the States table, but the column should be named professional_council_state_id instead of state_id.
How can I achieve this in my migration code?
Here is how it is right now:
class CreateProfessionals < ActiveRecord::Migration
def change
create_table :professionals do |t|
t.string :name, limit: 70
t.string :number, limit: 15
t.references :professional_council, index: true
t.references :occupation_code, index: true
t.timestamps null: false
end
add_foreign_key :professionals, :professional_councils
add_foreign_key :professionals, :occupation_codes
end
end
class CreateStates < ActiveRecord::Migration
def change
create_table :states do |t|
t.string :description, limit: 40, null: false
t.string :abbreviation, limit: 2, null: false
t.integer :ibge_code
t.timestamps null: false
end
end
end

Inheritance with ActiveRecord at the same time

I have a class 'Report' that has columns 'description', 'pending', etc.
/app/models/report.rb
class Report < ActiveRecord::Base
end
class CreateReports < ActiveRecord::Migration
def change
create_table :reports do |t|
t.boolean :pending, :default => true
t.boolean :accepted, :default => false
t.text :description
t.timestamps null: false
end
end
end
But I also have two other classes: ReportPost (when a User report a Post), and ReportTopic (when a User report a Topic). I used this approach because I can user 'belongs_to :topic' for ReportTopic and 'belongs_to :post' for ReportPost. So, here comes the problem:
Since ReportPost and ReportTopic have the same columns of 'Report', I need to use the inheritance from 'Report'. But I also need to use ActiveRecord inheritance to capture new attributes from :report_topic migrates.
But, how?
Here are the other classes:
class ReportTopic < Report
belongs_to :topic
end
class ReportPost < Report
belongs_to :post
end
`And, the migrates:
class CreateReportPosts < ActiveRecord::Migration
def change
create_table :report_posts do |t|
t.belongs_to :post
t.timestamps null: false
end
end
end
class CreateReportTopics < ActiveRecord::Migration
def change
create_table :report_topics do |t|
t.belongs_to :topic
t.timestamps null: false
end
end
end
You could use Single Table Inheritance (STI) in this case. Just add a column named 'type' to your report table.
def change
create_table :reports do |t|
t.boolean :pending, :default => true
t.boolean :accepted, :default => false
t.text :description
t.string :type
t.timestamps null: false
end
end
Rails will understand this as STI. Any subclass that you may create will have its type equal to the name of the class (e.g. type = 'ReportTopic')

Resources