Rails: Migrate doesn't work - ruby-on-rails

I have a little problem with my db schema.
I have create a migration named messages but it was no good so I deleted them for replace by the good messages migration.
But in my schema I have the last messages migration yet.
How it's possible?
rails db:migrate:status:
up 20160924085640 Create conversations
up 20160924090519 Create messages
schema.rb:
create_table "conversations", force: :cascade do |t|
t.integer "sender_id"
t.integer "recipient_id"
end
create_table "messages", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "subject"
t.string "body"
t.integer "recipient_id"
t.integer "sender_id"
end
migration:
class CreateMessages < ActiveRecord::Migration[5.0]
def change
create_table :messages do |t|
t.text :body
t.references :conversation, index: true
t.references :user, index: true
t.boolean :read, :default => false
t.timestamps
end
end
end
routes
resources :conversations do
resources :messages
end
When I try to access to /conversations
I have this error: uninitialized constant ConversationsController

First You should read about rails routes and their correspond action in controller
For Every Route
You should have one controller
one action in controller for desired route
and one view(erb) filw in views
Like for your query
In controller
Create index action
than in views => conversations => index.html.erb

Related

When I run rails db:migrate the migration doesn't fully work

class CreateMessages < ActiveRecord::Migration[5.2]
def change
create_table :messages do |t|
t.text :body
t.integer :user_id
t.timestamps
end
end
end
After running rails db:migrate my schema looks like this...
ActiveRecord::Schema.define(version: 2020_03_20_063104) do
create_table "messages", force: :cascade do |t|
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
I am wondering where the t.text "body" is and where the t.integer "user_id"is and why it isn't showing up in my schema under messages table.
I have checked migration status and all migrations have been ran.
If you ran something like this in your migration file
class CreateMessages < ActiveRecord::Migration[5.2]
def change
create_table :messages do |t|
t.timestamps
end
end
end
Messages table is created and after this you can't create another migration with create_table :messages. Like #Marek Lipka wrote on comments. Either you need to rollback your CreateMessages migration and chance file and run your migration again. Or you need to write another migration to change existing table like this.
class AddBodyAndUserIdToMessages < ActiveRecord::Migration[5.2]
def change
add_column :messages, :body, :text
add_column :messages, :user_id, :integer
end
end

Rails NoMethodError: undefined method `name' for "#<RecipeType:0x000055cd000b18a0>":String

I've been having trouble to do a challenge with Active Records, I read the documentation, and seen other examples with belongs_to that I remade and worked, I have no clue anymore about what I'm doing wrong here when I try to call recipe.recipe_type.name I get the error Rails NoMethodError: undefined method `name' for "#":String
schema.rb
create_table "recipe_types", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "recipe_type_id"
t.index ["recipe_type_id"], name: "index_recipe_types_on_recipe_type_id"
end
create_table "recipes", force: :cascade do |t|
t.string "title"
t.string "cuisine"
t.string "difficulty"
t.integer "cook_time"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "ingredients"
t.text "cook_method"
end
end
migrations
def change
create_table :recipes do |t|
t.string :title
t.string :cuisine
t.string :difficulty
t.integer :cook_time
t.timestamps
end
end
end
class AddFieldsToRecipe < ActiveRecord::Migration[5.2]
def change
add_column :recipes, :ingredients, :text
add_column :recipes, :cook_method, :text
end
end
class CreateRecipeTypes < ActiveRecord::Migration[5.2]
def change
create_table :recipe_types do |t|
t.string :name
t.timestamps
end
end
end
class AddRecipeRefToRecipeType < ActiveRecord::Migration[5.2]
def change
add_reference :recipe_types, :recipe_type, foreign_key: true
end
end
You seemed to have added the recipe_type reference to the wrong table. Your last migration should probably have been
add_reference :recipes, :recipe_type, foreign_key: true
because as it is, you have added the reference_type reference to ReferenceType.
So the final schema was:
ActiveRecord::Schema.define(version: 2020_03_26_013134) do
create_table "recipe_types", force: :cascade do |t|
t.string "name"
t.integer "recipe_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["recipe_id"], name: "index_recipe_types_on_recipe_id"
end
create_table "recipes", force: :cascade do |t|
t.string "title"
t.string "cuisine"
t.string "difficulty"
t.integer "cook_time"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "ingredients"
t.text "cook_method"
t.integer "recipe_type_id"
t.index ["recipe_type_id"], name: "index_recipes_on_recipe_type_id"
end
end
and with
models/recipe_type
class RecipeType < ApplicationRecord
has_many :recipes
end
models/recipe
class Recipe < ApplicationRecord
belongs_to :recipe_type
end
You can start a simple has_many belongs_to active record association, I hope this helps as many people as those who helped me, in the beginning of this journey, strongly recommend to study db:migrate, db:rollback, db:create and db:drop for those who encounter some trouble.

find a record that match another one (from another table)

I have three tables user, event, expected_event
My event are scrapped (every day with a rake task) from another
website
A user can create expected_event
So What I want to do is:
When a new event is found I want it to be compared to the Users expected_event...
If an event matches to any users expected_event then the users receive an email with the matching event (event.department, event.location_name)
I want to compare event.department to expected_event.department
I don't know how to do this...
expected_event.rb
class ExpectedEvent < ApplicationRecord
belongs_to :user
validates :department, presence: true
end
user.rb
class User < ApplicationRecord
has_many :expected_events
end
In the event model I have some methode to retreive city_name, location_nameand department
class Event < ApplicationRecord
def department
self.city[/\(.*?\)/].gsub(/[()]/, "").to_i
end
def city_name
self.city[/^[^\(]+/].rstrip!
end
def location_name
self.city[/\|(.*)/].gsub("|", "").strip
end
end
schema.rb
ActiveRecord::Schema.define(version: 20171210203403) do
create_table "events", force: :cascade do |t|
t.datetime "date"
t.string "city"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "nickname"
####
end
create_table "expected_events", force: :cascade do |t|
t.integer "department"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_expected_events_on_user_id"
end
end
EDIT
Is it correct if I add something like this to my user model?
has_many :matching_events, through: :events, source: :expected_events
When a new event is created, why don't you just query for ExpectedEvent records with matching paramters. Something like
event = Event.create(event_params)
if ExpectedEvent.where(city: event.city, ...).any?
#send email to user about the event
end

Can't write unknown attribute using rails_admin

Im' using rails_admin to save a project that has a category within. I didn't define project_id and category_id because I thought they should be created by rails. The problem I got were using the method def category_id=(id) defined in project model (see below). The error is:
can't write unknown attribute `project_id`
My models are:
Category
class Category < ActiveRecord::Base
belongs_to :project, :inverse_of => :category
end
Project
class Project < ActiveRecord::Base
has_one :category, :dependent => :destroy, :inverse_of => :project
def category_id
self.category.try :id
end
def category_id=(id)
self.category = Category.find_by_id(id)
end
end
My schema:
create_table "categories", force: :cascade do |t|
t.string "title"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "projects", force: :cascade do |t|
t.string "title"
t.text "text"
t.string "url"
t.string "key_feature"
t.string "image_1"
t.string "image_2"
t.string "image_3"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
How do you connect Projects to Categories?
Base on your schema Projects table has no category_id.
Neither you Category table has project_id
I would add category_id to Projects table.
rails g migration add_category_id_to_projects category_id:integer
rake db:migrate
The solution at the end was to manually add the project_id to categories table.
rails g migration add_project_id_to_categories project_id:integer
Thanks #Misha for you suggestion.

Entrys aren't being saved to my database correctly?

Here's my schema file..
ActiveRecord::Schema.define(:version => 20120505115340) do
create_table "clients", :force => true do |t|
t.string "name"
t.string "detail"
t.string "more_detail"
t.string "more_details"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "jobs", :force => true do |t|
t.string "name"
t.integer "number"
t.string "responsible"
t.string "monthly"
t.string "quarterly"
t.string "other"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
end
And here's my migration file's..
class CreateClients < ActiveRecord::Migration
def change
create_table :clients do |t|
t.string :name
t.string :detail
t.string :more_detail
t.string :more_details
t.timestamps
end
end
end
class CreateJobs < ActiveRecord::Migration
def change
create_table :jobs do |t|
t.string :name
t.integer :number
t.string :responsible
t.string :monthly
t.string :quarterly
t.string :other
t.timestamps
end
end
end
In my view file, I have it setup so that is pulls out the client.name and shows it to the user <%= link_to client.name, client_path(client) %>.
However, all im getting back when I create a new entry is /clients/1 instead of the name that I specified in my form.
When I try to migrate the DB nothing happens and then when I try to drop he DB to start afresh it tells me that it does even exist.
If I understand you correctly, you are concerned that your view displays a link to /clients/1 for your newly created object?
This is the default path when using Ruby on Rails, and is what will be produced by the path helper object_path(object) that you are using. This can be customized (see guides on routes.rb). If this is not a problem, then your application is working as intended.
BtW, the number used in the default path refers to the id given to the object. All objects stored using ActiveRecord will automatically get a unique id which can be used to identify the object. Just as the created_at and updated_at columns in your schema, the id column will be created regardless if you explicitly define it in your schema or not.
To reset your database (drop, recreate and migrate to current schema), use the following command:
rake db:reset
EDIT:
<%= link_to client.name, client_path(client) %>
Should result in the following HTML (where CLIENT_NAME is the name attribute of the client)
CLIENT_NAME

Resources