I understand that the answer may be in similar answers that I've read but I do not yet have the knowledge power to draw a solution from them.
I'm trying to seed a column in a rails model with an array:
["N1", "N2", "N3", "N4", "N5", etc ]
Each value will represent a new line (or entry? not sure of the correct terminology) in the database column.
Currently, similar to what has been suggested in a similar posts, I'm using:
[above array].each do |pc|
Postcodes.create!({ pcode => pc})
end
But I'm getting the following error:
NameError: uninitialized constant Postcodes
I've tried un-pluralising the model name and also un-capitalising but this does not seem to help.
db:schema:
ActiveRecord::Schema.define(version: 20151211095938) do
create_table "users", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.string "email"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
Model:
class Postcode < ActiveRecord::Base
end
Your model is names Postcode, not Postcodes (not the plural s). The following should work:
codes = ["N1", "N2", "N3", "N4", "N5"]
codes.each do |code|
Postcode.create!(pcode: code)
end
Related
I have a table that is part of a mountable blog engine in Rails. That table is called lines_articles.
def change
create_table "lines_articles", force: true do |t|
t.string "title"
t.string "sub_title"
t.text "content"
t.boolean "published", default: false
t.datetime "published_at"
t.string "hero_image"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "slug"
t.string "gplus_url"
t.boolean "featured", default: false
t.string "document"
t.string "short_hero_image"
end
I want to show all contents in that table in my rails console, so I ran a .classify to make sure I didn't screw up the plural variable, and the output was:
2.2.1 :015 > "lines_articles".classify
=> "LinesArticle"
So now the console confirmed the naming convention, but when I run a simple LinesArticle.all, I get an error: NameError: uninitialized constant LinesArticle.
How can the console classify a table name and throw a NameError when querying the table with that name?
You have to define a model class in the app/models/lines_article.rb directory.
If you're on Rails 5, it should look something like this:
class LinesArticle < ApplicationRecord
end
If you're on Rails 4, it should look something like this:
class LinesArticle < ActiveRecord::Base
end
Then re-open rails console and try again.
I'm following a course on coursera and I'm on my first assignment details of which can be found on this and this link. WHen I ran rspec I found the test cases to be failing, turned out my schema didn't have an ID column in it. In the course it said that when I run migration the ID column is generated automatically just like created_at and updated_at. Anyone has any idea why the id column probably didn't get generated. I know I can overcome the problem by specifying it in a new migration but just wanted to know the reason.
Here's the Schema I currently have:
ActiveRecord::Schema.define(version: 20161108162529) do
create_table "profiles", force: :cascade do |t|
t.string "gender"
t.integer "birth_year"
t.string "first_name"
t.string "last_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "todo_items", force: :cascade do |t|
t.date "due_date"
t.string "title"
t.text "description"
t.boolean "completed", default: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "todo_lists", force: :cascade do |t|
t.string "list_name"
t.date "list_due_date"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "username"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
This is the migrations for todolists:
class CreateTodoLists < ActiveRecord::Migration
def change
create_table :todo_lists do |t|
t.string :list_name
t.date :list_due_date
t.timestamps null: false
end
end
end
The model class it generated:
class TodoList < ActiveRecord::Base
end
My method that is inserting a record in it in the assignment.rb file as asked:
def create_todolist(params)
# accept a hash of todolist properties (`:name` and `:due_date`) as an input parameter. Note these are not 100% the same as Model class.
# use the TodoList Model class to create a new user in the DB
# return an instance of the class with primary key (`id`), and dates (`created_at` and `updated_at`) assigned
t1 = TodoList.new
t1.list_name = params["name"]
t1.list_due_date = params["due_date"]
t1.save
TodoList.first
end
rspec code that is failing:
context "rq03.2 assignment code has create_todolist method" do
it { is_expected.to respond_to(:create_todolist) }
it "should create_todolist with provided parameters" do
expect(TodoList.find_by list_name: "mylist").to be_nil
due_date=Date.today
assignment.create_todolist(:name=> 'mylist', :due_date=>due_date)
testList = TodoList.find_by list_name: 'mylist'
expect(testList.id).not_to be_nil
expect(testList.list_name).to eq "mylist"
expect(testList.list_due_date).to eq due_date
expect(testList.created_at).not_to be_nil
expect(testList.updated_at).not_to be_nil
end
Actual message that I get when it fails the test:
Failures:
1) Assignment rq03 rq03.2 assignment code has create_todolist method should create_todolist with provided parameters
Failure/Error: expect(testList.id).not_to be_nil
NoMethodError:
undefined method `id' for nil:NilClass
# ./spec/assignment_spec.rb:173:in `block (4 levels) in <top (required)>'
# ./spec/assignment_spec.rb:14:in `block (2 levels) in <top (required)>'
The schema won't show the ID column. I double checked with one of my rails apps:
db/schema.rb
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "first_name"
t.string "last_name"
end
And when I describe the table in Postgres with \d users, I see the id column:
Column | Type | Modifiers
------------------------+-----------------------------+----------------------------------------------------
id | integer | not null default nextval('users_id_seq'::regclass)
email | character varying | not null default ''::character varying
first_name | character varying |
last_name | character varying |
If there is a reason you don't want the ID, you can omit it by passing id: false to create_table.
create_table :users, id: false do |t|
#...
end
Probably a horrible idea on the users table :-)
Update
Looks like you are not actually creating a new TodoList.
The clue here is in the error: "undefined method 'id' for nil:NilClass". Your testList is nil.
One good tip is to always use the ActiveRecord's "bang" methods in tests. This will cause them to throw an exception if they fail. Which is super helpful when trying to track down errors -- you'll find the place with the actual error and not some side effect down the line.
I bet you can update your create_todolist to help track this down
def create_todolist(params)
# Updated: To use ActiveRecord create! method.
# This will throw an exception if it fails.
TodoList.create!(list_name: params[:name], due_date: params[:due_date])
end
I would also update your spec, by changing:
testList = TodoList.find_by list_name: 'mylist'
To use the bang:
testList = TodoList.find_by! list_name: 'mylist'
I have two models connected with a has_and_belongs_to_many association: courses and semesters. rails_admin was only giving me the option to add semesters when creating a course, and not the other way around (and really, it's much more useful to add courses when creating a semester). I made some tweaks the migration:
def change
create_table "courses", force: :cascade do |t|
t.string "department"
t.integer "number"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "semesters", force: :cascade do |t|
t.integer "year"
t.string "season"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "semesters_courses", id: false, force: :cascade do |t|
t.integer "semester_id"
t.integer "course_id"
end
add_index "semesters_courses", ["course_id"], name: "index_semesters_courses_on_course_id"
add_index "semesters_courses", ["semester_id"], name: "index_semesters_courses_on_semester_id"
end
I renamed the intermediary table to semesters_courses from courses_semesters, just for clarity. Not only did this not solve the problem, but now when I try to add a new course, it 500s and tells me:
Could not find table 'courses_semesters'
I know I could make this go away by changing the name back, but I'm not sure where railsadmin is getting that name from (and suspect this to be the source of my problem). I've removed and reinstalled railsadmin, dropped and rewritten the tables, and cleared my browser's cache. When I search my entire project tree for "courses_semesters," I only get results in my error log.
New at Rails dev, so I assume I'm missing some config file somewhere that I need to update, but would love some help on where to find it.
You’re overwriting the join table name.
Option 1 you MUST specify the name of the join table in your models
app/models/course.rb
has_and_belongs_to_many :semesters, join_table: "semesters_courses"
app/models/semester.rb
has_and_belongs_to_many :courses, join_table: "semesters_courses"
Or Option 2 just rename your join table to "courses_semesters" by using migration.
rails g migration rename_courses_semesters
class RenameCoursesSemesters < ActiveRecord::Migration
def self.up
rename_table :semesters_courses, :courses_semesters
end
def self.down
rename_table :courses_semesters, :semesters_courses
end
end
Hope this answers your question.
I am running into SQLiteException that seems to be causing problem.
Schema.rb
create_table "features", force: :cascade do |t|
t.string "name_key"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "features", ["name_key"], name: "index_features_on_name_key"
create_table "organizations", force: :cascade do |t|
t.string "name"
t.string "code"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "organizations_features", id: false, force: :cascade do |t|
t.integer "organization_id"
t.integer "feature_id"
end
This is current schema and i explicity created table organizations_features(still through migration but a separate migration that references a join table) as otherwise create_join_table would create "features_organizations". In that process, if i run
rake db:drop db:create db:schema:load
I still keep getting the following error even without loading a single record in any tables(i never ran db:seed).
ActiveRecord::StatementInvalid: SQLite3::SQLException: near ")": syntax error: INSERT INTO "organizations_features" () VALUES ()
The other question seem to suggest to make the join table name all singular as in organization_feature, but since we share the schema with other services, it is imperative that we use the same naming conventions.
Note: even i tried to create table using migration "create_join_table" the problem seem to persist"
Update : seeds.rb
organization = Organization.create!(name: 'XYZ', code: 'xyz')
feature = Feature.create!(name_key: 'Some Feature')
user = User.create!(name: "user1",
email: "user#abcd.org",
password: "password123",
password_confirmation: "password123",
profile_id: profile.id)
OrganizationsFeature.create!(feature_id: feature.id, organization_id: organization.id)
where OrganizationsFeature looks like this
class OrganizationsFeature < ActiveRecord::Base
belongs_to :organization
belongs_to :feature
end
I found answer to the question in case if someone else runs into the same issue. The test/fixtures/organizations_features.yml file has null records
one :{}
two: {}
which was causing null records to be inserted into the table. This data is loaded every time and hence insert error.
Having proper data/deleting the file solved the issue.
I am trying to set up a search function in Rails. I have a table called documents. I can search on the subject and the text in the body. Where I am having an issue is trying to to search on fields in associated tables. I have a table called authors. I want to be able to put a name in the author field and return the documents matching that author.
class Search < ActiveRecord::Base
has_many :documents
def search_documents
documents = Document.all
documents = documents.where("subject like ?", "%#{subject}%") if subject.present?
documents = documents.where("body like ?", "%#{text}%") if text.present?
documents = documents.author.where("author like ?", "%#{author}%") if author.present?
return documents
end
end
The subject and body works fine. I've tried all kinds of variations on the author line with no luck . The schema for my documents model looks as follows with author_id linking to the authors table on a has_many relationship between docs and authors
create_table "documents", force: :cascade do |t|
t.string "subject"
t.text "body"
t.integer "category_id"
t.integer "tag_id"
t.integer "author_id"
t.integer "reviewer_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "document_attachment_file_name"
t.string "document_attachment_content_type"
t.integer "document_attachment_file_size"
t.datetime "document_attachment_updated_at"
t.integer "attached_files_id"
t.string "token"
end
Is there a way to reference the author's name in
documents.author.where("author like ?", "%#{author}%") if author.present?
Right now, I am getting an error as follows
Showing C:/Users/cmendla/RubymineProjects/Rl2/app/views/searches/show.html.erb where line #9 raised:
undefined method author' for #<Document::ActiveRecord_Relation:0xa20a0f8>
Rails.root: C:/Users/cmendla/RubymineProjects/Rl2
Application Trace | Framework Trace | Full Trace
app/models/search.rb:12:insearch_documents'
app/views/searches/show.html.erb:9:in `_app_views_searches_show_html_erb__631448441_64839156'
thx
documents.joins(:author).where("authors.name like ?", "%#{author}%") if author.present?
This assumes that the name of the author is stored in a column called name in the authors table and the Document model has a belongs_to :author.