Related
I'm new to Ruby on Rails and I got two problems where I need some help:
I got the tables "cases" and "users". The table case includes the column "first name" and "last name". Now I want to add a unique string (pseudonymization) to each case for a special kind of identification without using the ID. This string should be build from the third letter of the first name and the total amount of letters plus the third letter of the last name and again the total amount of letters of the last name. E.g. for the name "Bill Smith" the string would be: L4I5.
Now the "users" should be able to find a specific case using that created special string. There should be a kind of a searching field where they can type in the string and click on search. Then the case with all the parameters should be shown.
What is the best way, to implement these two functions/features? I'm using rails 6.0.3.4 and ruby 2.7.0.
For better understanding see my schema.rb below.
ActiveRecord::Schema.define(version: 2021_01_28_100706) do
create_table "cases", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.string "gender"
t.date "birthdate"
t.string "place_of_residence"
t.string "diagnosis"
t.bigint "user_id"
t.datetime "confirmed_at"
t.datetime "created_at", precision: 6
t.datetime "updated_at", precision: 6, null: false
t.bigint "diagnosis_id"
t.bigint "district_id"
t.bigint "report_id"
t.index ["diagnosis_id"], name: "index_cases_on_diagnosis_id"
t.index ["district_id"], name: "index_cases_on_district_id"
t.index ["report_id"], name: "index_cases_on_report_id"
t.index ["user_id"], name: "index_cases_on_user_id"
end
create_table "diagnoses", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "illness"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "districts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "name"
t.string "place"
t.integer "postal_code"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.bigint "state_id", null: false
t.index ["state_id"], name: "index_districts_on_state_id"
end
create_table "reports", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
t.bigint "district_id"
t.text "comment"
t.datetime "date"
t.bigint "user_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["district_id"], name: "index_reports_on_district_id"
t.index ["user_id"], name: "index_reports_on_user_id"
end
create_table "states", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "titel"
t.string "abbr"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", 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.integer "role"
t.string "first_name"
t.string "last_name"
t.bigint "district_id"
t.bigint "state_id"
t.index ["district_id"], name: "index_users_on_district_id"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
t.index ["state_id"], name: "index_users_on_state_id"
end
end
You could add a column to the case table and a callback in the model to set it how you want. And to search just add a scope
#migration
add_column :cases, :new_column, :string, index: true
#model
class Case < ApplicationRecord
before_create :set_new_column
scope :by_new_column, ->(term) { where('new_column = ?', term) }
...
private
def set_new_column
self.new_column = "#{first_name[0]}#{last_name.length}"
end
end
Then in your controller or where ever, you could use like:
Case.by_new_column("C5")
Users can upload tracks and create playlist. I have a model for playlist and i have a model for playlist_track which is for users that can save to the playlist. I can create a new playlist but how do i add the tracks to the playlist in the views?
ActiveRecord::Schema.define(version: 2018_12_06_050857) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "active_storage_attachments", force: :cascade do |t|
t.string "name", null: false
t.string "record_type", null: false
t.bigint "record_id", null: false
t.bigint "blob_id", null: false
t.datetime "created_at", null: false
t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
end
create_table "active_storage_blobs", force: :cascade do |t|
t.string "key", null: false
t.string "filename", null: false
t.string "content_type"
t.text "metadata"
t.bigint "byte_size", null: false
t.string "checksum", null: false
t.datetime "created_at", null: false
t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
end
create_table "playlist_tracks", force: :cascade do |t|
t.integer "playlist_id"
t.integer "track_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "playlists", force: :cascade do |t|
t.string "title"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "plays", force: :cascade do |t|
t.integer "user_id"
t.integer "track_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "tracks", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "genre"
t.integer "user_id"
t.string "name"
t.date "release_date"
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", null: false
t.datetime "updated_at", null: false
t.string "username"
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 "active_storage_attachments", "active_storage_blobs", column: "blob_id"
end
Here is my track model
class Track < ApplicationRecord
has_many_attached :mp3
belongs_to :user, optional: true
has_many :playlist_tracks
has_many :playlists, through: :playlist_tracks
has_many :plays
end
and here is my playist_track model
class PlaylistTrack < ApplicationRecord
belongs_to :playlist
belongs_to :track
end
I deployed my rails app to Heroku. I am trying to use the Heroku console to add categories to my app but I do not know the commands.
Controller:
class PortfolioController < ApplicationController
def index
#posts = Post.all.order("created_at DESC")
end
def about
end
def portfolio
end
def contact
end
def webapp
category = Category.find_by_category('webapp')
#posts = Post.where(category_id: category.id)
end
def art
category = Category.find_by_category('gameart')
#posts = Post.where(category_id: category.id)
end
end
Schema:
ActiveRecord::Schema.define(version: 20160910220215) do
create_table "admins", 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.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "admins", ["email"], name: "index_admins_on_email", unique: true
add_index "admins", ["reset_password_token"], name: "index_admins_on_reset_password_token", unique: true
create_table "categories", force: :cascade do |t|
t.string "category"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "posts", force: :cascade do |t|
t.string "title"
t.text "content"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.integer "category_id"
end
end
To create a category in the rails/heroku console under your table Categories simply run:
Category.connection
Then:
Category.create(name: "NAME_OF_CATEGORY")
It will then create a category as such:
#<Category id: 1, name: "NAME_OF_CATEGORY", created_at: "2016-09-14 22:25:14", updated_at: "2016-09-14 22:25:14">
Im attempting to rake my migrations on my heroku distro. im getting this error:
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedTable: ERROR: relation "plants" does not exist
: ALTER TABLE "images" ADD CONSTRAINT "fk_rails_d5e1aedcb5"
FOREIGN KEY ("plant_id")
REFERENCES "plants" ("id")
Some of my tables go through, but not this one, im not sure what is even going on here. It works in development, but not in production.
Here is my schema file:
ActiveRecord::Schema.define(version: 20160521081000) do
create_table "appointments", force: :cascade do |t|
t.string "task"
t.datetime "time"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
end
create_table "cycles", force: :cascade do |t|
t.string "title"
t.datetime "completed_at"
t.boolean "completed"
t.integer "tray_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.datetime "due_date"
end
add_index "cycles", ["tray_id"], name: "index_cycles_on_tray_id"
create_table "datalogs", force: :cascade do |t|
t.integer "tray_id"
t.float "ambcur"
t.float "ambmin"
t.float "ambmax"
t.float "folcur"
t.float "folmin"
t.float "folmax"
t.float "ph"
t.float "heatmat"
t.float "h202"
t.float "tds"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "datalogs", ["tray_id"], name: "index_datalogs_on_tray_id"
create_table "events", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "grows", force: :cascade do |t|
t.string "title"
t.text "notes"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "category_id"
t.integer "user_id"
end
create_table "images", force: :cascade do |t|
t.string "file_id"
t.integer "plant_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "tray_id"
end
add_index "images", ["plant_id"], name: "index_images_on_plant_id"
create_table "nutrient_calcs", force: :cascade do |t|
t.string "product"
t.integer "vegtime"
t.integer "flowertime"
t.float "rezsize"
t.string "rezunits"
t.boolean "aerstone"
t.string "outputunits"
t.integer "nutrient_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "nutrient_calcs", ["nutrient_id"], name: "index_nutrient_calcs_on_nutrient_id"
create_table "nutrients", force: :cascade do |t|
t.string "title"
t.string "manufacturer"
t.float "price"
t.string "unit"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "pages", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "pics", force: :cascade do |t|
t.string "title"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "plant_cycles", force: :cascade do |t|
t.string "title"
t.integer "interval"
t.integer "frequency"
t.integer "plant_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "plant_cycles", ["plant_id"], name: "index_plant_cycles_on_plant_id"
create_table "plantdats", force: :cascade do |t|
t.float "ambtemp"
t.float "foltempcur"
t.float "foltempmin"
t.float "foltempmax"
t.float "ph"
t.float "heatmat"
t.integer "tds"
t.float "h202"
t.integer "plant_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.float "ambtempmin"
t.float "ambtembmax"
end
add_index "plantdats", ["plant_id"], name: "index_plantdats_on_plant_id"
create_table "plants", force: :cascade do |t|
t.string "title"
t.text "notes"
t.integer "category_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "species"
t.integer "tray_id"
t.integer "species_id"
t.integer "user_id"
end
add_index "plants", ["category_id"], name: "index_plants_on_category_id"
add_index "plants", ["tray_id"], name: "index_plants_on_tray_id"
add_index "plants", ["user_id"], name: "index_plants_on_user_id"
create_table "schedules", force: :cascade do |t|
t.integer "schedulable_id"
t.string "schedulable_type"
t.date "date"
t.time "time"
t.string "rule"
t.string "interval"
t.text "day"
t.text "day_of_week"
t.datetime "until"
t.integer "count"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "species", force: :cascade do |t|
t.string "name"
t.text "description"
t.integer "plant_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "species", ["plant_id"], name: "index_species_on_plant_id"
create_table "tasks", force: :cascade do |t|
t.integer "plant_id"
t.integer "tray_id"
t.string "title"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.datetime "due_date"
end
add_index "tasks", ["plant_id"], name: "index_tasks_on_plant_id"
add_index "tasks", ["tray_id"], name: "index_tasks_on_tray_id"
create_table "tray_cycles", force: :cascade do |t|
t.string "title"
t.integer "tray_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "tray_cycles", ["tray_id"], name: "index_tray_cycles_on_tray_id"
create_table "trays", force: :cascade do |t|
t.string "title"
t.text "notes"
t.integer "category_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.integer "rescap"
end
add_index "trays", ["category_id"], name: "index_trays_on_category_id"
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.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.string "firstname"
t.string "lastname"
t.string "username"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
Also, my app gets pushed to Heroku, but when I go to 'sign_up', I get the error from the heroku logs:
2016-05-22T07:53:31.678059+00:00 app[web.1]: ActionView::Template::Error (undefined method `firstname' for #<User:0x007fa667e33798>):
2016-05-22T07:53:31.678049+00:00 app[web.1]:
2016-05-22T07:53:31.678060+00:00 app[web.1]: 25:
2016-05-22T07:53:31.678061+00:00 app[web.1]: 26: <div class="field">
2016-05-22T07:53:31.678062+00:00 app[web.1]: 27: <%= f.label 'First Name' %><br />
2016-05-22T07:53:31.678063+00:00 app[web.1]: 28: <%= f.text_field :firstname, autofocus: true, rows: 10, cols: 10, class: 'form-control', placeholder: 'ENTER FIRST NAME' %>
2016-05-22T07:53:31.678064+00:00 app[web.1]: 29: </div>
2016-05-22T07:53:31.678065+00:00 app[web.1]: 30:
2016-05-22T07:53:31.678065+00:00 app[web.1]: 31: <div class="field">
Can anyone help me figure this out? Many thanks :)
Apparently one of the migration files got lost.
If the migration directory is quite full, or not consistent with the database you can use rake db:schema:load to directly create the whole DB.
Thanks to #xyious in the comments. Somehow a few migrations got deleted unbeknownst to me. Running heroku run rake db:schema:load
fixed the problem.
I am trying to write a scope or a method where I take the attribute (last_eaten) of an instance (line_item) and compare it to the current date. If last_eaten has a date of 1-7 days ago, it gets put in an array that will be called last_week. If last_eaten has a date of 8-14 days ago, it gets put in an array that will be called 2_weeks_ago.
I've tried quite a few things as you can see with the commented out code and several things that I had already erased, but I can't get anything to work. I'm relatively new to rails and any help would be greatly appreciated.
Model
class LineItem < ActiveRecord::Base
belongs_to :recipe
belongs_to :recipe_collection
#scope :last_week, lambda {where("line_item.last_eaten >= ?", 7.days.ago)}
#scope :last_week, lambda { |weeks| where("last_eaten > ?", weeks) }
#scope :three_weeks, lambda { where( #line_item.last_eaten < 21.days.ago.to_date) }
##line_item = LineItem.where(last_eaten: params[:last_eaten]) -- returns nil
##line_item = LineItem.where(last_eaten: params[:last_eaten] < 21.days.ago.to_date)
#def menu
# list = []
# if LineItem.last_eaten.day.to_i > 21.days.ago.day.to_i
# LineItem.last_eaten.each do |recipe_id|
# LineItem.recipe_id << list
# end
# end
# list
#end
end
Schema
ActiveRecord::Schema.define(version: 20151229223926) do
create_table "directions", force: :cascade do |t|
t.text "step"
t.integer "recipe_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "directions", ["recipe_id"], name: "index_directions_on_recipe_id"
create_table "ingredients", force: :cascade do |t|
t.string "name"
t.integer "recipe_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "ingredients", ["recipe_id"], name: "index_ingredients_on_recipe_id"
create_table "line_items", force: :cascade do |t|
t.integer "recipe_id"
t.integer "recipe_collection_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.date "last_eaten"
end
add_index "line_items", ["recipe_collection_id"], name: "index_line_items_on_recipe_collection_id"
add_index "line_items", ["recipe_id"], name: "index_line_items_on_recipe_id"
create_table "recipe_collections", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "recipes", force: :cascade do |t|
t.string "title"
t.text "description"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
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.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
scope :last_week, lambda {where("line_item.last_eaten >= ?", 7.days.ago)}
should work...
But further reading made me realise that your table is called line_items, not line_item
When you're doing sql-snippets, you need to refer to the name of the table in SQL, rather than treating it like an individual rails object's name. This means always use the pluralised version :)