In my web app, I have nodes and links. A link has two nodes. One node is a source node, and the other node is a target node. Basically, I want source and target columns in the database that hold references to nodes. I am trying to figure out how to implement this.
Here is the migration for the nodes model:
class CreateNodes < ActiveRecord::Migration
def change
create_table :nodes do |t|
t.string :name
t.integer :group
t.references :link, index: true
t.timestamps
end
end
end
Here is the node model:
class Nodes < ActiveRecord::Base
belongs_to :link
end
I am trying to figure out how to set up the migration for the links model. Here is what I have so far:
class CreateLinks < ActiveRecord::Migration
def change
create_table :links do |t|
t.integer :value
t.boolean :checked
t.timestamps
end
end
end
Here is what I have in my model:
class Links < ActiveRecord::Base
has_many :nodes
end
Would the correct migration look like this?
class CreateLinks < ActiveRecord::Migration
def change
create_table :links do |t|
t.integer :value
t.boolean :checked
t.references :source
t. references :target
t.timestamps
end
end
end
t.references :smith is basically a shortcut for t.integer :smth_id so if your Nodes belong to Links, then yes that construction seems correct.
not sure where your links#source and links#target point to though.
Related
I have two models 'Tutorial' and 'Tutorialcategory'
class Tutorialcategory < ActiveRecord::Base
has_many :tutorials
class Tutorial < ActiveRecord::Base
belongs_to :tutorialcategory
Tutorials are associated with multiple categories like html,rubyonrails where html and ruby on rails are tutorialcategories
followings are migrations
class CreateTutorials < ActiveRecord::Migration
def change
create_table :tutorials,force: true do |t|
t.string :title
t.text :body
t.integer :rating
t.string :videoid
t.belongs_to :tutorialcategory
t.timestamps
end
end
end
class CreateTutorialcategories < ActiveRecord::Migration
def change
create_table :tutorialcategories do |t|
t.string :title
t.timestamps null:false
end
end
end
All tutorials are listing properly on index page but when I see category page it gives me following error
PG::Error: ERROR: column tutorials.tutorialcategory_id does not exist
I have no idea why you named your model Tutorialcategory instead of TutorialCategory which follow Rails naming convention and make it easier to understand.
Firstly, rollback your db one step
rake db:rollback
Change your migration file to:
class CreateTutorials < ActiveRecord::Migration
def change
create_table :tutorials,force: true do |t|
t.string :title
t.text :body
t.integer :rating
t.string :videoid
t.belongs_to :tutorial_category, index: true
t.timestamps
end
end
end
class CreateTutorialCategories < ActiveRecord::Migration
def change
create_table :tutorial_categories do |t|
t.string :title
t.timestamps null:false
end
end
end
Run the migration again and edit your model to match with new schema.
class TutorialCategory < ActiveRecord::Base
has_many :tutorials
class Tutorial < ActiveRecord::Base
belongs_to :tutorial_category
I have this table structure:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :username
t.string :email
t.string :encrypted_password
t.string :salt
t.timestamps
end
end
end
And I want to add a new table as shown below:
class CreateHolidays < ActiveRecord::Migration
def change
create_table :holidays do |t|
t.string :earn_leave
t.string :seek_leave
t.string :unplanned_leave
t.timestamps
t.timestamps
end
add_index(users,id)
end
end
What should I do for this, please also suggest commands that can/should be used for migration.
You want to look up about foreign_keys:
#app/models/holiday.rb
class Holiday < ActiveRecord::Base
belongs_to :user
end
#app/models/user.rb
class User < ActiveRecord::Base
has_many :holidays
end
This will mean you have to add the user_id foreign key to your holidays data table:
class CreateHolidays < ActiveRecord::Migration
def change
create_table :holidays do |t|
t.references :user
t.string :earn_leave
t.string :seek_leave
t.string :unplanned_leave
t.timestamps
t.timestamps
end
end
end
You must remember that Rails is designed to be built on top of a relational database. As such, it uses foreign_keys in the tables to locate associated records:
The above will allow you to call:
#user.holidays
and
#holiday.user
I have a DB that stores students answers to quiz questions. These are linked to Student Learning Outcomes that I want to review through a series of relationships described below. I am trying to do a count for how many questions were answered correctly and how many questions were answered incorrectly for each student learning outcome, but I keep receiving errors. Thank you in advance for any help you provide.
The general mapping is
“Answer” answers a question that tests a “KnowledgeTopic” that covers many (“KtCoveredBySLO”) “StudentLearningOutcome”
My models have the following relationships:
class Answer < ActiveRecord::Base
belongs_to :KnowledgeTopic
end
class KnowledgeTopic < ActiveRecord::Base
has_many :answers
has_many :kt_covered_by_slos
has_many :student_learning_outcomes, through: :kt_covered_by_slos
end
class KtCoveredBySlo < ActiveRecord::Base
belongs_to :StudentLearningOutcome
belongs_to :KnowledgeTopic
end
class StudentLearningOutcome < ActiveRecord::Base
has_many :kt_covered_by_slos
has_many :knowledge_topics, through: :kt_covered_by_slos
end
The query I am attempting to run is:
#answers = Answer.joins(:KnowledgeTopic => {:kt_covered_by_slos => :StudentLearningOutcome})
.select( 'student_learning_outcomes.id As student_learning_outcomes_id',
:is_correct, "count(answers.id) AS total_answers")
.group('student_learning_outcomes.id', :is_correct)
The error I am receiving is:
SQLite3::SQLException: no such column:
kt_covered_by_slos.knowledge_topic_id: SELECT
student_learning_outcomes.id As student_learning_outcomes_id,
"answers"."is_correct", count(answers.id) AS total_answers FROM
"answers" INNER JOIN "knowledge_topics" ON "knowledge_topics"."id"
= "answers"."KnowledgeTopic_id" INNER JOIN "kt_covered_by_slos" ON "kt_covered_by_slos"."knowledge_topic_id" = "knowledge_topics"."id"
INNER JOIN "student_learning_outcomes" ON
"student_learning_outcomes"."id" =
"kt_covered_by_slos"."StudentLearningOutcome_id" GROUP BY
student_learning_outcomes.id, is_correct
Migrations:
class CreateKtCoveredBySlos < ActiveRecord::Migration
def change
create_table :kt_covered_by_slos do |t|
t.references :StudentLearningOutcome, index: true
t.references :KnowledgeTopic, index: true
t.timestamps
end
end
end
class CreateAnswers < ActiveRecord::Migration
def change
create_table :answers do |t|
t.references :Question, index: true
t.references :Section, index: true
t.references :Student, index: true
t.references :KnowledgeTopic, index: true
t.boolean :is_correct
t.string :answer_text
t.references :Enroll, index: true
t.timestamps
end
end
end
class CreateKnowledgeTopics < ActiveRecord::Migration
def change
create_table :knowledge_topics do |t|
t.string :knowledge_area
t.string :knowledge_unit
t.string :knowledge_topic
t.integer :year_added
t.boolean :active
t.integer :correct_answers
t.integer :incorrect_answers
t.integer :temp_correct_answer
t.integer :temp_incorrect_answer
t.timestamps
end
end
end
class CreateStudentLearningOutcomes < ActiveRecord::Migration
def change
create_table :student_learning_outcomes do |t|
t.string :accredidation_body
t.string :title
t.string :description
t.integer :year_added
t.boolean :active
t.integer :correct_answers
t.integer :incorrect_answers
t.integer :temp_correct_answer
t.integer :temp_incorrect_answer
t.timestamps
end
end
end
Thanks Everyone. Using Ave's explanation, I changed the reference names, and then updated everything else accordingly. After that I was able to run the query with
#answers = Answer.joins(knowledge_topic: :student_learning_outcomes)
.select( 'student_learning_outcomes.id As student_learning_outcomes_id', :is_correct,
"count(answers.id) AS total_answers")
.group('student_learning_outcomes.id', :is_correct)
I have models:
Category:
class Category < ActiveRecord::Base
has_many :entities, as: :resourcable
end
class CreateCategories < ActiveRecord::Migration
def change
create_table :categories do |t|
t.string :name
t.text :short_descr
t.text :full_descr
t.timestamps
end
end
end
Language:
class Language < ActiveRecord::Base
has_many :entities, as: :resourcable, dependent: :destroy
validates :code, uniqueness: true
end
class CreateLanguages < ActiveRecord::Migration
def change
create_table :languages do |t|
t.string :name
t.string :code
t.timestamps
end
end
end
And Entity:
class Entity < ActiveRecord::Base
belongs_to :language
belongs_to :resourcable, polymorphic: true
end
class CreateEntities < ActiveRecord::Migration
def change
create_table :entities do |t|
t.integer :language_id
t.string :name
t.text :short_descr
t.text :full_descr
t.references :resourcable, polymorphic: true
t.timestamps
end
end
end
In Categories there are default values for fields (short_descr, full_descr), In Entities there are translations for this fields. I need to render as json all Categories with appropriate translations: at first, I need to take Language with appropriate code (for example ru), next, I need to find all language Entities for this language, next, if Entity have filled short_descr and full_descr I need to render Category with this values, else I need to render the Category with default values (this values in Categories table). How to do this? I prefer ActiveRecord buy consider pure SQL.
EDITED
Now I'm trying to use gem 'squeel':
Language.joins{entities.category}.
select{coalesce(entities.short_descr, categories.short_descr)}.
where{languages.code == 'en'}
but it doesn't work (undefined methodshort_descr' for nil:NilClass`). There is the problem?
Entity.joins(:language, :category).
select('categories.*, coalesce(entities.short_descr, categories.short_descr) as short_descr,
coalesce(entities.full_descr, categories.full_descr) as full_descr').
where('languages.code = ?', 'en')
Sorry, i'am newbie
I have database:
Migrate
-Mst_group tble
class CreateMstGroups < ActiveRecord::Migration
def self.up
create_table :mst_groups do |t|
t.string :group_name
end
end
end
-Mst_japan
class CreateMstJapans < ActiveRecord::Migration
def self.up
create_table :mst_japans do |t|
t.string :name_level
end
end
end
-Tbl_user
class CreateTblUsers < ActiveRecord::Migration
def self.up
create_table :tbl_users do |t|
t.string :login_name, :null =>false,:limit =>15
t.string :password,:null =>false,:limit =>50
t.string :full_name,:null =>false
t.string :full_name_kana
t.string :email,:null =>false
t.string :tel,:null =>false,:limit =>15
t.date :birthday,:null =>false
t.references :mst_groups
end
end
end
-Tbl_detail_user_japan
class CreateTblDetailUserJapans < ActiveRecord::Migration
def self.up
create_table :tbl_detail_user_japans do |t|
t.date :start_date
t.date :end_date
t.integer :total
t.references :tbl_users
t.references :mst_japans
end
end
end
Model
class MstGroup < ActiveRecord::Base
has_many :tbl_users
end
class MstJapan < ActiveRecord::Base
has_many :tbl_detail_user_japans
end
class TblUser < ActiveRecord::Base
belongs_to :mst_group
has_one :tbl_detail_user_japan
end
class TblDetailUserJapan < ActiveRecord::Base
belongs_to :tbl_user
belongs_to :mst_japan
end
Controller
def index
#user= ???????
end
How to write command select : login_name, full_name, full_name_kana, email, tel, group_name, name_lever, start_date, end_date, total in controller
It depends on how you want to retrieve the User object. You need to tell Rails how to find the TblUser object. If, for example, the user ID is known, let's say in a variable called 'id' then you would do:
def index
#user=TblUser.find(id)
end
It depends on your application logic how Rails would know which user you need. You may need an input from the user in case of log in, etc.
(Typically in Rails you would call the table 'Users', by convention tables and classes have the same name and then you wouldn't need to call the class TblUser)
That is all you need in the controller, you don't need to tell it which fields you want.
Then in the View you can access all the fields:
Fields on TblUser, example:
<%= #user.email %>
You can access the fields from related objects through the relations, example:
<%= #user.mst_group.group_name %>
Hope that helps to get you started.