Home > Back-end >  Rails has_many_through query not returning results
Rails has_many_through query not returning results

Time:12-16

I have some models with a has_many_through join. I am trying to get a list of classification_fields and their properties where the classification_id is in the array I am pasing through. This following query doesn't seem to be getting anything. What am I doing wrong?

Get the parent ids and query the classificationfields:

@parentids = @classification.self_and_ancestors_ids.to_a if params[:class_id].present?
@details = ClassificationField.includes(:classifications).where(classification_id: [@parentids] ) if params[:sub].present?

classification model:

belongs_to :parent, class_name: "Classification", optional: true
has_many :children, class_name: "Classification", foreign_key: "parent_id", dependent: :destroy

has_many :class_fields
has_many :fields, through: :class_fields, source: :classification_field

accepts_nested_attributes_for :fields, allow_destroy: true

has_closure_tree

classification_field model:

has_many :class_fields
has_many :classifications, through: :class_fields

class_fields model:

belongs_to :classification
belongs_to :classification_field

Form where I am rendering dynamic form fields based on the classification fields details:

<%= form.fields_for :properties, OpenStruct.new(@sr.properties) do |builder| %>
  <% @details.each do |field| %>
    <%= render "srs/fields/#{field.field_type}", field: field, form: builder %>
  <% end %>
<% end %>

Schema:

enable_extension "plpgsql"

  create_table "class_fieldmembers", force: :cascade do |t|
    t.integer "classification_id"
    t.integer "classification_field_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "class_fields", force: :cascade do |t|
    t.bigint "classification_id", null: false
    t.bigint "classification_field_id", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["classification_field_id"], name: "index_class_fields_on_classification_field_id"
    t.index ["classification_id"], name: "index_class_fields_on_classification_id"
  end

  create_table "classification_fields", force: :cascade do |t|
    t.string "name"
    t.string "field_type"
    t.string "required"
    t.string "classification_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "displayname"
  end

  create_table "classification_hierarchies", force: :cascade do |t|
    t.integer "ancestor_id", null: false
    t.integer "descendant_id", null: false
    t.integer "generations", null: false
    t.index ["ancestor_id", "descendant_id", "generations"], name: "classification_anc_desc_idx", unique: true
    t.index ["descendant_id"], name: "classification_desc_idx"
  end

  create_table "classifications", force: :cascade do |t|
    t.string "name"
    t.string "displayname"
    t.text "description"
    t.boolean "inuse"
    t.integer "sort_order"
    t.integer "parent_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "srs", force: :cascade do |t|
    t.string "summary"
    t.text "description"
    t.string "status"
    t.string "priority"
    t.bigint "user_id", null: false
    t.bigint "classification_id", null: false
    t.text "properties"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["classification_id"], name: "index_srs_on_classification_id"
    t.index ["user_id"], name: "index_srs_on_user_id"
  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.boolean "admin"
    t.string "first_name"
    t.string "last_name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

  add_foreign_key "class_fields", "classification_fields"
  add_foreign_key "class_fields", "classifications"
  add_foreign_key "srs", "classifications"
  add_foreign_key "srs", "users"

Query results from console:

[1] pry(main)> ClassificationField.includes(:classifications).where(classification_id: [1, 6] )
  ClassificationField Load (0.7ms)  SELECT "classification_fields".* FROM "classification_fields" WHERE "classification_fields"."classification_id" IN ($1, $2)  [["classification_id", "1"], ["classification_id", "6"]]
  ClassificationField Load (0.6ms)  SELECT "classification_fields".* FROM "classification_fields" WHERE "classification_fields"."classification_id" IN ($1, $2) /* loading for inspect */ LIMIT $3  [["classification_id", "1"], ["classification_id", "6"], ["LIMIT", 11]]
=> #<ClassificationField::ActiveRecord_Relation:0x4a10>

Any help is appreciated.

CodePudding user response:

Try this. Convert query result to array of objects using .to_a

@details = ClassificationField.includes(:classifications).where(classification_id: [1, 6] ).to_a

CodePudding user response:

I think I have it now.

@details = ClassificationField.joins(:class_fields).where(class_fields: {classification_id: [@parentids]}).to_a if params[:sub].present?
  • Related