Rake Setup - ActiveRecord::RecordInvalid: Validation failed: - activerecord

In trying to run a setup rake tasks(to populate my dbase). It is telling me that questions must exist. When I do a count on 'Question.count' - it returns 4 - so I know questions exist.
What am I missing? typo? syntax? When I look at similiar SO, it shows as some sort of typo but I am not seeing it.
Here is the code that is not working:
def add_option_group
puts " * Add Option Groups...\n"
OptionGroup.transaction do
create_option_group(
option_group_name: "Always-Never",
question_id: Question.find_by(question_name: "Do you have an updated photo?")
)
create_option_group(
option_group_name: "Yes-No",
question_id: Question.find_by(question_name: "Do you have a bio saved (updated in last 12 months)?")
)
end
end
def create_option_group(options={ })
puts " * CREATE OptionGroup Section...\n"
option_group_attributes = {}
attributes = option_group_attributes.merge options
option_group = OptionGroup.create! attributes
option_group.save!
option_group
end
I am getting this error message:
Add Option Groups...
CREATE OptionGroup Section...
rake aborted!
ActiveRecord::RecordInvalid: Validation failed: Questions must exist
/Users/axxx/workspace/fresh-assess/lib/tasks/setup.rake:314:in create_option_group' /Users/axxx/workspace/fresh-assess/lib/tasks/setup.rake:298:in block in add_option_group'
/Users/axxx/workspace/fresh-assess/lib/tasks/setup.rake:297:in add_option_group' /Users/axxx/workspace/fresh-assess/lib/tasks/setup.rake:51:in create_sample_data!
Migration files:
***** migrations ******
class CreateOptionGroups < ActiveRecord::Migration[6.1]
def change
create_table :option_groups do |t|
t.bigint :question_id
t.text :option_group_name
t.timestamps
end
end
end
class CreateQuestions < ActiveRecord::Migration[6.1]
def change
create_table :questions do |t|
t.bigint :assessment_section_id
t.bigint :input_type_id
t.text :question_name
t.string :question_subtext
t.boolean :question_required_yn
t.boolean :answer_required_yn
t.boolean :allow_multiple_options_answers_yn
t.integer :dependent_question_id
t.integer :dependent_question_option_id
t.integer :dependent_answer_id
t.timestamps
end
end
end
Here is schema
t.bigint "question_id"
t.bigint "option_choice_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "questions", force: :cascade do |t|
t.bigint "assessment_section_id"
t.bigint "input_type_id"
t.text "question_name"
t.string "question_subtext"
t.boolean "question_required_yn"
t.boolean "answer_required_yn"
t.boolean "allow_multiple_options_answers_yn"
t.integer "dependent_question_id"
t.integer "dependent_question_option_id"
t.integer "dependent_answer_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
Add foreign key:
class ForeignMoreKeysToModels < ActiveRecord::Migration[6.1]
def change
add_foreign_key :option_groups, :questions, validate: false
add_foreign_key :option_choices, :option_groups, validate: false
end
end
In the model:
class Question < ApplicationRecord
has_one :assessment_section
belongs_to :assessment_section, optional: true
has_many :option_groups
end
class OptionGroup < ApplicationRecord
has_many :option_choices
belongs_to :questions
end
What am I missing?
thx.

Two issues:
In the OptionGroup class, it should say belongs_to :question.
Try adding .id to the question lookup:
create_option_group(
option_group_name: "Always-Never",
question_id: Question.find_by(question_name: "Do you have an updated photo?").id
)

Related

Ancestry gem gives error "The scope body needs to be callable." in rails 4?

models/message.rb
class Message < ActiveRecord::Base
has_ancestry
end
schema.rb
create_table "messages", force: :cascade do |t|
t.text "content"
t.integer "parent_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "ancestry"
end
after adding has_ancestry in model it gives error Argument Error.
"The scope body needs to be callable."
Please help me
Thanks

ActiveRecord::StatementInvalid at /category/5

I am a new developer working on a Sinatra/Ruby/ActiveRecord app. I have established a 1:many (postgres) relationship between Category and Recipe. When I try to list the recipes in a category I get the error:
ActiveRecord::StatementInvalid at /category/5
PG::UndefinedColumn: ERROR: column recipes.category_id does not exist LINE 1: SELECT 1 AS one FROM "recipes" WHERE "recipes"."category_id... ^ : SELECT 1 AS one FROM "recipes" WHERE "recipes"."category_id" = $1 LIMIT 1
file: postgresql_adapter.rb location: prepare line: 637
app.rb
get('/category/:id') do
#category = Category.find(params.fetch('id'))
#recipes = #category.recipes
erb(:category)
end
category.erb
<% if #recipes.any?() %>
<% #recipes.each() do |recipe| %>
<ul>
<li><a href='/recipe/<%=recipe.id%>'> <%=recipe.recipe_name%></a></li>
</ul>
<%end%>
<%else %>
<p>You have no recipes!</p>
<%end%>
schema
ActiveRecord::Schema.define(version: 20150930234556) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "categories", force: :cascade do |t|
t.string "cat_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "images", force: :cascade do |t|
t.string "image_name"
t.string "url"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "alt"
t.integer "width"
t.integer "height"
t.integer "recipe_id"
end
create_table "ingredients", force: :cascade do |t|
t.string "ingredient_name"
t.integer "recipe_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "instructions", force: :cascade do |t|
t.string "instruction_name"
t.integer "recipe_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "recipes", force: :cascade do |t|
t.string "recipe_name"
t.string "source"
t.string "servings"
t.string "comment"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "cat_id"
end
end
I have searched my project folders and cannot find category_id. Don't know why it's looking for that, my field names are category.id and recipe.cat_id.
This:
#recipes = #category.recipes
suggests that you have
has_many :recipes
in your Category model. That has_many will be looking for a category_id column in your recipes table (i.e. a category_id attribute in your Recipe model). But you don't have a recipes.category_id column, you have a recipes.cat_id column:
create_table "recipes", force: :cascade do |t|
#...
t.integer "cat_id"
end
I'd recommend renaming the recipes.cat_id column to recipes.category_id to match the conventions that Rails has a very strong preference for. If you can't rename the column then add a :foreign_key option to that has_many to tell Category how to resolve the relationship:
has_many :recipes, :foreign_key => :cat_id

Rails ActiveRecord relationships, STI, and inheritance

OK, so it's been years since I've written any ruby code, and my design may be incorrect. With that in mind, I'm writing a small utility to clone project entities in TargetProcess via REST. Target Process has a data model that allows for several types of parent:child relationships:
project:epic:feature:user_story
project:feature:user_story
project:user_story
However, all the entities are nearly identical from a data structure perspective, so it seemed to make sense to use STI and use models to define the relationships and inheritance. I've created a new Rails app with only these models to verify the error I'm getting when I attempt to associate an Epic with a Feature:
ActiveModel::MissingAttributeError: can't write unknown attribute `epic_id`
Here are the models:
class TargetProcessEntity < ActiveRecord::Base
end
class Project < TargetProcessEntity
has_many :epics
has_many :features
has_many :user_stories
end
class Project < TargetProcessEntity
has_many :epics
has_many :features
end
class Epic < TargetProcessEntity
belongs_to :project
has_many :features
end
class Feature < TargetProcessEntity
belongs_to :project
belongs_to :epic
has_many :user_stories
end
class UserStory < TargetProcessEntity
belongs_to :feature
belongs_to :project
end
Here is the schema:
ActiveRecord::Schema.define(version: 20150929122254) do
create_table "epics", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "target_process_entity_id"
t.integer "project_id"
end
add_index "epics", ["project_id"], name: "index_epics_on_project_id"
add_index "epics", ["target_process_entity_id"], name: "index_epics_on_target_process_entity_id"
create_table "features", force: :cascade do |t|
t.integer "project_id"
t.integer "epic_id"
t.integer "target_process_entity_id"
end
add_index "features", ["epic_id"], name: "index_features_on_epic_id"
add_index "features", ["project_id"], name: "index_features_on_project_id"
add_index "features", ["target_process_entity_id"], name: "index_features_on_target_process_entity_id"
create_table "projects", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "target_process_entity_id"
end
add_index "projects", ["id"], name: "index_projects_on_id"
add_index "projects", ["target_process_entity_id"], name: "index_projects_on_target_process_entity_id"
create_table "target_process_entities", force: :cascade do |t|
t.string "type", null: false
t.string "name"
t.text "description"
t.integer "source_remote_id"
t.float "numeric_priority"
t.integer "owner"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "cloned_remote_id"
t.string "resource_type"
t.integer "project_id"
end
create_table "user_stories", force: :cascade do |t|
t.integer "project_id"
t.integer "feature_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "target_process_entity_id"
end
add_index "user_stories", ["feature_id"], name: "index_user_stories_on_feature_id"
add_index "user_stories", ["project_id"], name: "index_user_stories_on_project_id"
add_index "user_stories", ["target_process_entity_id"], name: "index_user_stories_on_target_process_entity_id"
end
While Epic and Feature both have a project_id, an instance of Feature does not have an epic_id attribute; attempting to assign an epic to feature blows up:
[20] pry(main)> epic = Epic.new
=> #<Epic:0x007fcab6c80590
id: nil,
type: "Epic",
name: nil,
description: nil,
source_remote_id: nil,
numeric_priority: nil,
owner: nil,
created_at: nil,
updated_at: nil,
cloned_remote_id: nil,
resource_type: "Epic",
project_id: nil>
[21] pry(main)> feature = Feature.new
=> #<Feature:0x007fcab6d3ba48
id: nil,
type: "Feature",
name: nil,
description: nil,
source_remote_id: nil,
numeric_priority: nil,
owner: nil,
created_at: nil,
updated_at: nil,
cloned_remote_id: nil,
resource_type: "Feature",
project_id: nil>
[22] pry(main)> epic.save
(0.1ms) begin transaction
SQL (0.3ms) INSERT INTO "target_process_entities" ("type", "resource_type", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["type", "Epic"], ["resource_type", "Epic"], ["created_at", "2015-10-02 15:18:13.351578"], ["updated_at", "2015-10-02 15:18:13.351578"]]
(4.6ms) commit transaction
=> true
[23] pry(main)> feature.epic = epic
ActiveModel::MissingAttributeError: can't write unknown attribute `epic_id`
from /Users/kcallahan/.rbenv/versions/2.0.0-p647/lib/ruby/gems/2.0.0/gems/activerecord-4.2.4/lib/active_record/attribute.rb:138:in `with_value_from_database'
[24] pry(main)>
I realize it is extremely possible I am either doing something wrong or have made a poor design decision; any input is hugely appreciated as I've not been able to find anything on this and have been banging my head against it for days!
OK, I got it working almost by mistake! I added the xxx_id columns to the target_process_entities table. I assumed that the STI tables would be able to respond to the relationship definitions, though my understanding of the inner workings of STI and relationships are rusty and incomplete at best...
I may be wrong but it looks like your Feature table is a join table for many to many relationship between Project and Epic.
If that's the case, your models might look like this
class Project < TargetProcessEntity
has_many :features
has_many :epics, through: :features
end
class Epic < TargetProcessEntity
has_many :features
has_many :projects, through: :features
end
class Feature < TargetProcessEntity
belongs_to :project
belongs_to :epic
has_many :user_stories
end
the source is implied if you use the same name
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

How do I properly add a foreign key in active record?

I'm trying to create some referential integrity across several tables, and am tripping over the placement of add foreign keys. At best the statement is ignored, worst it throws an error.
class CreateCantons < ActiveRecord::Migration
def change
create_table :cantons do |t|
t.integer :canton_id
t.string :canton_name
t.timestamps null: false
end
end
end
class CreateResources < ActiveRecord::Migration
def change
create_table :resources do |t|
t.integer :resource_id
t.string :resource_name
t.integer :type_id
t.integer :canton_id
t.string :url
t.string :address
t.string :city
t.string :state
t.string :zip
add_foreign_key :cantons, :canton_id #ignored
add_foreign_key :types, :type_id #ignored
t.timestamps null: false
end
end
end
class CreateResourceContacts < ActiveRecord::Migration
def change
create_table :resource_contacts do |t|
t.integer :contact_id
t.integer :resource_id
add_foreign_key :resources, :resource_id
add_foreign_key :contacts, :contact_id
t.timestamps null: false
end
end
end
adding a t in front throws an error
t.add_foreign_key :contacts, :contact_id #error
How do I properly use this command?
you need to move the foreign_keys outside of the create table
class CreateResources < ActiveRecord::Migration
def change
create_table :resources do |t|
t.integer :resource_id
t.string :resource_name
t.integer :type_id
t.integer :canton_id
t.string :url
t.string :address
t.string :city
t.string :state
t.string :zip
t.timestamps null: false
end
add_foreign_key :resources, :cantons
add_foreign_key :resources, :types
end
end
see http://edgeapi.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-add_foreign_key
And also you need to tell it what tables you are adding it to.

How to use created_at value as default in Rails

How can I set one of my database table to created_at as default value. I did this but didn't work, I have checked in the DB and the value of code is null.
class CreateEvents < ActiveRecord::Migration
def change
create_table :events do |t|
t.string :title
t.string :location
t.text :description
t.date :occurs_on
t.string :code, :default => Event::created_at
t.timestamps
end
end
end

Resources