rails admin has_many through relationship leading to errors - ruby-on-rails

I am using rails_admin gem for admin interface.
I have a has_many through relationship which doesn't seem to work with rails admin.
class Company < ActiveRecord::Base
has_many :talent_infos, class_name: 'CompanyTalentInfo'
has_many :talents, through: :talent_infos
end
class CompanyTalentInfo < ActiveRecord::Base
belongs_to :company
belongs_to :talent
end
class Talent < ActiveRecord::Base
has_many :talent_infos, class_name: 'CompanyTalentInfo'
has_many :companies, through: :talent_infos
end
I get error every time I try to create a new company and my guess is that its the first time when rails_admin tries to check the relationships and it doesn't accept my current associations.
The error I get is this file gems/rails_admin-0.7.0/app/views/rails_admin/main/_form_filtering_multiselect.html.haml:21
21 controller.list_entries(config, :index, field.associated_collection_scope, false).map { |o| [o.send(field.associated _object_label_method), o.send(field.associated_primary_key)] }.sort_by {|a| [selected_ids.index(a[1]) || selected_ids.si ze, i+=1] }
I get this error
undefined method `klass' for nil:NilClass`
Can anyone help me with this association how can I fix it.

perhaps a late response, but could you compare the relevant part of your database schema with the following and let me know the difference? I believe the relations are setup correctly so that should be the problem.
create_table "companies", force: :cascade do |t|
t.string "name"
end
create_table "company_talent_infos", force: :cascade do |t|
t.string "metadata"
t.integer "company_id"
t.integer "talent_id"
end
create_table "talents", force: :cascade do |t|
t.string "name"
end

Related

Find all records whose association has a nil association in turn

Given the models below:
class Score < ApplicationRecord
belongs_to :composition
end
class Composition < ApplicationRecord
has_many :scores
has_one :invoice, dependent: :destroy
end
class Invoice < ApplicationRecord
belongs_to :composition
end
what's the best way to find the scores, whose composition has a nil invoice?
I tried:
Score.joins(:composition).where(composition: {invoice: nil})
csn = Composition.includes(:invoice).where(invoices:{id:nil})
Score.where(csn.include? composition)
Score.where(csn.map(&:id).include? composition_id)
Score.where(Composition.left_outer_joins(:invoice).where(invoices:{id:nil}).includes? composition)
all with errors. Any ideas?
EDIT: here are the corresponding tables as per schema.rb:
create_table "compositions", force: :cascade do |t|
...
end
create_table "invoices", force: :cascade do |t|
t.integer "composition_id"
...
t.index ["composition_id"], name: "index_invoices_on_composition_id", using: :btree
end
create_table "scores", force: :cascade do |t|
t.integer "composition_id", null: false
...
end
Please try following query:
Score.joins(:composition).includes(composition: : invoice).where(invoices: { id: nil })
Try following
Score.joins(:composition).where('compositions.invoice_id IS NULL')
above should work, Have a good luck!!!
Please try following query,
Score.joins(:composition).where('compositions.id NOT IN (?)', Invoice.pluck(:composition_id))
If this not work then let me know the columns present in compositions and scores tables

Rails complex association

I have this models:
class Product < ActiveRecord::Base
has_many :feature_products, -> { where("taxonomy_slug = feature_taxonomy_slug") }
has_many :features, through: :feature_products, class_name: "Feature", source: :feature
end
class Feature < ActiveRecord::Base
has_many :feature_products, -> (object){ where(" feature_taxonomy_slug = ?", object.taxonomy_slug) }, primary_key: :external_id
has_many :products, through: :feature_products
end
class FeatureProduct < ActiveRecord::Base
belongs_to :product
belongs_to :feature, primary_key: :external_id
end
and the tables are like this:
create_table "feature_products", force: :cascade do |t|
t.integer "product_id"
t.integer "feature_id"
t.string "feature_taxonomy_slug"
end
create_table "features", force: :cascade do |t|
t.integer "external_id"
t.string "name"
t.string "taxonomy_slug"
end
create_table "products", force: :cascade do |t|
t.integer "company_id"
end
I want to be able to create feature products association like this:
feature = Feature.create(external_id: 1234, name: 'WS', taxonomy_slug: 'prop')
Product.create(name: 'XXX', features: [feature])
The problem is the table feature_products, it stores the ids but it doesn't store the feature_taxonomy_slug from the feature. Is there any way to store it?
I think if you want to save the slug in the FeatureProduct model then you are going to have to create one explicitly, i.e.
FeatureProduct.create(product: product, feature: feature, feature_taxonomy_slug: feature.taxonomy_slug)
I do not understand why you want to save the slug in the FeatureProduct model.
Is there a reason why you do not want to access it through the product.features association?

has_and_belongs_to_many UndefinedTable: ERROR

I have two models, Clinician and Patient. A clinician has_many: patients and a patient belongs_to :clinician. A join table, shared_patients is meant to store additional associations between patients and clinicians as a patient can be shared by many other clinicians besides the one it belongs_to. This is done using a has_and_belongs_to_many relationship.
See models:
class Clinician < ActiveRecord::Base
has_many :patients
has_and_belongs_to_many :shared_patients, join_table: 'shared_patients', class_name: 'Patient'
end
class Patient < ActiveRecord::Base
belongs_to :clinician
has_and_belongs_to_many :shared_clinicians, join_table: 'shared_patients', class_name: 'Clinician'
end
This is how my tables are set out in the db schema:
create_table "clinicians", force: true do |t|
t.string "first_name"
t.string "last_name"
t.integer "user_id"
end
create_table "patients", force: true do |t|
t.integer "clinician_id"
t.string "first_name"
t.string "last_name"
t.integer "user_id"
end
create_table "shared_patients", id: false, force: true do |t|
t.integer "clinician_id"
t.integer "patient_id"
end
Using these I would like to show the list of clinicians that a patient is shared with.
Right now I am getting an error:
PG::UndefinedTable: ERROR: relation "shared_patients" does not exist
LINE 1: INSERT INTO "shared_patients" ("clinician_id", "id", "patien...
If I try and create a relationship in console:
#shared = SharedPatient.new("id"=>1, "clinician_id"=>2526, "patient_id"=>1307)
=> #1, "clinician_id"=>2526, "patient_id"=>1307}>
#shared.save
Any advice on solving this error or on structuring the models to get the associations I want would be great. Thanks
When you have a has_and_belongs_to_many then you cannot have a class for the join table, ie. you can't have SharedPatient and you can't try using it as you've done.

Errors when using Rails has_many :through association

My app consists of exercises that users add to workouts. Users can create exercises or select existing ones.
*** UPDATE ****
I've added a model per Ben's solutions.
I'm receiving errors as below when attempting to add exercises to workouts. Is my syntax wrong? I've attempted soltions like this:
w=Workout.last
e=Exercise.last
w.exercises.build(:exercise => e) # NameError: uninitialized constant Workout::ExercisesWorkout
w.exercises_workouts.create(:exericse_id => 1) #NameError: uninitialized constant Workout::ExercisesWorkout
I'm confused by the new methods attached from the association as well as "_" or not, camelCase, Pluralize, symbol..etc.
Rails seems to be looking for the class ExercisesWorkout yet I define "exercises_workouts" and/or ExercisesWorkouts.
Thanks.
I'm having trouble adding exercises to workouts from the rails console. 2 potential issues that I see:
I don't know the proper syntax to do this (build, create, find)
Application setup properly (join table, models,..etc.)
Please let me know where my error is and if there is a better structure / association to use.
Thank you.
Models:
class Exercise < ActiveRecord::Base
has_many :workouts, :through => :exercises_workouts
has_many :exercises_workouts
end
class Workout < ActiveRecord::Base
has_many :exercises, :through => :exercises_workouts
has_many :exercises_workouts
end
class ExercisesWorkouts < ActiveRecord::Base
belongs_to :exercise
belongs_to :workout
end
schema.db:
ActiveRecord::Schema.define(version: 20141129181911) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "exercises", force: true do |t|
t.string "name"
t.string "description"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "exercises_workouts", id: false, force: true do |t|
t.integer "exercise_id", null: false
t.integer "workout_id", null: false
end
create_table "workouts", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
end
ERROR:
w=Workout.new #create new workout
w.name = 'test' #name workout
w.save #save workout
e1=Exercise.new #create new exercise
e1.name='press' #name exercise
e1.save #save exercise
#I'm not sure of the syntax here... I've tried alot between create, build using symbols and finds...., this is just one example..
w.exercises.create(e1) #NameError: uninitialized constant Workout::ExercisesWorkout
You also need a model for the join table:
class ExercisesWorkouts < ActiveRecord::Base
belongs_to :exercise
belongs_to :workout
end
Here is answer that covers join tables in more detail, if you're interested:
What would the joining table called in this case in Rails 3.1?

Forms and Routes for Has Many Through Relation in Rails4

I am a Rails newbie and trying to create a simple Rails4 application. I have User model which is generated by Devise GEM, Examination model and Participation models are both generated by scaffold generator.
These are my models:
class Examination < ActiveRecord::Base
has_many :participations
has_many :users, :through => :participations
end
class Participation < ActiveRecord::Base
belongs_to :user
belongs_to :examination
end
class User < ActiveRecord::Base
has_many :participations
has_many :examinations, :through => :participations
end
And Database Structure:
create_table "participations", force: true do |t|
t.integer "user_id"
t.integer "examination_id"
t.string "exam_language_preference"
....
end
create_table "users", force: true do |t|
t.string "email"
t.string "first_name"
....
end
create_table "examinations", force: true do |t|
t.string "name"
t.string "shortname"
t.datetime "exam_date"
end
Now, I would like to create the structure to make Users to be able to register to exams. In the index page of Examinations (app/views/examinations/index.html.erb) I want to add a "Register" button just next to default Show, Edit and Destroy buttons for each exam. When user click to "Register" button I want them to see a page where they can choose their exam language preference and submit their registrations.
Also I want a User can only 1 time register for an exam. I mean they can register for many exams but only 1 time for each.
I read the whole Rails Guide but couldn't find the right answer.
How can I do this kind of application?
Well, you're not going to find the answer for your specific question in rails guides. :)
I'd suggest that you read more on:
Validate uniqueness of an attribute using the scope option
Nested resources

Resources