How to import data into rails models from a table in a database - ruby-on-rails-5

I have the following schema in my rails app:
ActiveRecord::Schema.define(version: 20161020060112) do
create_table "authors", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "languages", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "quotes", force: :cascade do |t|
t.string "title"
t.date "date"
t.string "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "author_id"
t.integer "language_id"
t.integer "source_id"
t.index ["author_id"], name: "index_quotes_on_author_id"
t.index ["language_id"], name: "index_quotes_on_language_id"
t.index ["source_id"], name: "index_quotes_on_source_id"
end
create_table "source_types", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "sources", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "source_type_id"
t.index ["source_type_id"], name: "index_sources_on_source_type_id"
end
end
And this is the schema of the table that I want to import data from:
CREATE TABLE quotation_data(
id integer primary key,
author_name text,
source_type text,
source text,
language text,
date text,
title text,
body text
);
I did find some posts on Stackoverflow but none that tell about importing data from a single table into fields distributed over many models.
Thanks!

I have imported data from database I create the list that list everything that I have inserted in the database.
like:
Under controller#show
def show
#quotes = Quote.all
end
views#show
<ul>
<% #quotes.each do |quote| %>
<li>
<%= link_to quotes.title, edit_quotes_path(quote) %>
</li>
<% end %>
</ul>
This will help you to view what is on the database and edit it also.

Related

How to convert SQL into activerecord Rails

My sql that gives me the results I want (a single record from books table).
select *
from books
where book_number = ? and id not in (select book_id from checkout_logs where returned_date is null) limit 1
my best active record attempt:
#book = Book.where(book_number: params[:book_number]).where.not(id: CheckoutLog.where(returned_date: nil)).find(1)
? is the params[:book_number]
here is my Rails schema.rb
ActiveRecord::Schema.define(version: 2020_12_30_171415) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "books", force: :cascade do |t|
t.string "title"
t.string "author"
t.string "genre"
t.string "subgenre"
t.integer "pages"
t.string "publisher"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "book_number"
end
create_table "checkout_logs", force: :cascade do |t|
t.datetime "checkout_date"
t.datetime "due_date"
t.datetime "returned_date"
t.bigint "user_id", null: false
t.bigint "book_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["book_id"], name: "index_checkout_logs_on_book_id"
t.index ["user_id"], name: "index_checkout_logs_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.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.boolean "admin", default: 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 "checkout_logs", "books"
add_foreign_key "checkout_logs", "users"
end
The idea is I want to get a single book (id) from the book table with a given book_number (think ISBN) that doesn't have a record in checkout_log table with a matching book_id and a null for returned_date. (indicating a book is checked out and not available.)
EDIT: changed the last part from .take to .find(1) which now does take 1 record, problem is the
.where.not(id: CheckoutLog.where(returned_date: nil))
part isn't filtering out the books which have a checkout_log record and no returned_date.
.where.not(id: CheckoutLog.where(returned_date: nil))
=> I think you are filtering wrong id, you need to filter by book's id, not id of CheckoutLog.
So your query should be:
.where.not(id: CheckoutLog.where(returned_date: nil).pluck(:book_id))
Use of the includes query method may help.
Book.includes(:checkout_logs).where("books.book_number=? AND checkout_logs.returned_date IS NOT NULL", params[:book_number]).limit(1)
More info on query methods is in the api

How to add a new column in a migration file

I'm using Ruby on rails and Sqlite and I got the rspec and factorybot gems. And i'm on Linux ubuntu.
Migration
class CreateArticles < ActiveRecord::Migration[6.0]
def change
create_table :articles do |t|
t.string :title
t.string :description
t.integer :price
t.string :picture
t.string :author
t.timestamps
end
end
end
Schema.rb
ActiveRecord::Schema.define(version: 2020_02_07_071425) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "articles", force: :cascade do |t|
t.string "title"
t.string "description"
t.integer "price"
t.string "picture"
t.string "author"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
end
article.rb
FactoryBot.define do
factory :article do
title { Faker::Company.name }
description { Faker::Lorem.paragraph(sentence_count: 35)}
price { Faker::Number.decimal(l_digits: 2) }
picture { Faker::Company.logo }
author { Faker::FunnyName.two_word_name }
end
end
I just want add a new row like counter 0, but I tried everything (db:migrate, reset, modify all files..) every time my counter is undefined.
What do I need to do?

SQL Query in two different Rails models that have no association

I have a landlords table, and landlord_addresses table, and a landlord_companies table. From the landlords index view and using the landlords_controller I need to be able to search the landlord_companies, BUT landlords and landlord_companies have no ActiveRecord association with each other. Obviously I can't use what I've written below, but I am not sure how to search the landlord_companies ...any help would be great!
#landlord = #landlords.includes(:landlord_company)
.references(:landlord_companies)
.where("landlord_companies.llc_name LIKE ?", "%#{params[:landlord_llc_search]}%")
Schema:
create_table "landlords", force: :cascade do |t|
t.string "name"
t.string "contact_name"
t.string "contact_number"
t.integer "listing_agent_id"
t.boolean "own_application"
t.boolean "own_credit"
t.boolean "accepts_roommate_matchups"
t.boolean "management_company"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "landlord_companies", force: :cascade do |t|
t.string "llc_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "landlord_address_id"
end
I was able to figure this out and actually use the SQL query I had already written. I thought there was no association, but technically there was using a through.
Landlord.rb
has_many :landlord_companies, through: :landlord_addresses

Most efficient way to get a Users Tags

I have a somewhat complicated database structure in a Ruby on Rails project. A User can have many EmailAccounts, an EmailAccount can have many Subscriptions (many-to-many via a join table), and a Subscription can have many Tags (also many-to-many)
create_table "users", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.date "dob"
t.string "gender"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "email_accounts", force: :cascade do |t|
t.integer "user_id"
t.string "email"
t.string "provider"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "account_subscriptions", force: :cascade do |t|
t.integer "email_account_id", null: false
t.integer "subscription_id", null: false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "subscriptions", force: :cascade do |t|
t.string "email"
t.datetime "created_at"
t.datetime "updated_at"
t.string "domain"
end
create_table "sub_tags", force: :cascade do |t|
t.integer "subscription_id", null: false
t.integer "tag_id", null: false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "tags", force: :cascade do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
I want to see which Tags apply to a User through this relationship. Whats the most efficient way to do so (eager load all the relationships and loop through them, do a multi-level join in Postgres, etc)?
Assuming you have the right models
user = User.find(user_id)
tags = Tag.where(:id => SubTag.where(:subscription_id => AccountSubscription.where(:email_account_id => user.email_accounts.map{|e| e.id}).map{|a_s| a_s.subscription_id}).map{|s_t| s_t.tag_id})
tag_name = tags.map{|t| t.name}
this should work fine given you have the right indexes.

How can i use data from antoher tables in a active record where in rails

im trying to make a search form in a table that contains two ids as values, one of them is the id of an user and the other is the id of a project.
Here is my database schema:
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.text "bio"
t.float "lastLatitude"
t.float "lastLongitude"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "swipes"
t.string "profile_image"
end
create_table "projects", force: :cascade do |t|
t.string "name"
t.text "bio"
t.integer "user_id"
t.string "salary"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "likes"
t.string "image"
t.float "latitude"
t.float "longitude"
end
create_table "matches", force: :cascade do |t|
t.integer "user_id"
t.integer "project_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
What i want to do is to create a search form in the matches index view to filter the matches by the user name or the project name, but i don't know how to do it, this is what i have right now:
def self.search(search)
if search
where('User(user_id).name LIKE :search OR Project.name LIKE :search', search: "%#{search}%")
else
where(nil)
end
end
Is it possible to do that?
Any help is welcome
I suggest a scope approach
class Match < ActiveRecord::Base
belongs_to :project
belongs_to :user
scope name, ->(n) {
joins(:user, :project).where("users.name like ? or projects.name like ? ", "%#{n}%", "%#{n}%")
}
end
class User < ActiveRecord::Base
has_many :projects
scope :name, ->(n) {
where("users.name like ?", "%n%")
}
end
class Project < ActiveRecord::Base
scope :name, ->(n) {
where("projects.name like ?", "%n%")
}
end