Counting Members Based on Invitations - Query - ruby-on-rails

I am counting many user generated actions and for the most part it's easy, but with regard to one, more complex query, I am having trouble.
I have an invitations model and a user model and I can easily count the number of invitations the user sent, but I want to count the number of new members that signed up based on the invitations the existing member sent out.
In invitations, the invitees email is saved as recipient_email
Then, I know I can check that against new members email some how, but am not clear on the syntax.
Any help will be greatly appreciated. More information below.
Invitation Model:
class Invitation < ActiveRecord::Base
attr_accessible :recipient_email, :sender_id, :sent_at, :token
belongs_to :sender, :class_name => 'User'
has_one :recipient, :class_name => 'User'
validates_presence_of :recipient_email
validates_uniqueness_of :recipient_email, :message => '%{value} has already been invited'
validate :recipient_is_not_registered
validate :sender_has_invitations, :if => :sender
default_scope order: 'invitations.created_at DESC'
before_create :generate_token
before_create :decrement_sender_count, :if => :sender
after_create do |invitation|
InvitationMailer.delay.invitation_email(self)
end
def invitee
User.find_by_email(self.recipient_email)
end
def invitee_registered?
!invitee.blank?
end
def invitee_submitted?
!invitee.try(:submissions).blank?
end
private
def recipient_is_not_registered
errors.add :recipient_email, 'is already registered' if User.find_by_email(recipient_email)
end
def sender_has_invitations
unless sender.invitation_limit > 0
errors.add_to_base "You have reached your limit of invitations to send.
You can contact Lumeo if you'd like to request more."
end
end
def generate_token
self.token = Digest::SHA1.hexdigest([Time.now, rand].join)
end
def decrement_sender_count
sender.decrement! :invitation_limit
end
end
User Model:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :mailchimp
attr_accessible :name, :email, :password, :password_confirmation,
:remember_me, :role_id, :role_ids, :image_attributes,
:terms, :profile_attributes, :current, :image, :roles,
:invitation_token, :join_mailing_list, :affiliate_id,
:invitation_affiliate_token, :affiliation, :referrer_id
validates_uniqueness_of :email
VALID_NAME_REGEX = /[\w]+([\s]+[\w]+){1}+/
validates :name, presence: true,
format: {with: VALID_NAME_REGEX}
#invitation
has_many :sent_invitations, :class_name => 'Invitation', :foreign_key => 'sender_id'
belongs_to :invitation
def invitation_token
invitation.token if invitation
end
def invitation_token=(token)
self.invitation = Invitation.find_by_token(token)
end
before_create :set_invitation_limit
has_one :invitation_affiliate, :class_name => "Affiliate", :foreign_key => 'token', :primary_key => 'invitation_affiliate_token'
private
def set_invitation_limit
self.invitation_limit = 100
end
end
Invitation and User Tables:
create_table "users", :force => true 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
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 "role_id"
t.string "name"
t.integer "invitation_id"
t.integer "invitation_limit"
end
create_table "invitations", :force => true do |t|
t.integer "sender_id"
t.string "recipient_email"
t.string "token"
t.datetime "sent_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end

I could think of two different ways:
Add accepted field in invitations
You could add a boolean field for invitations named accepted, the default value will be false and you set it to true when the receipent accepts the invitation. Then you create a scope named accepted that returns only accepted invitations
scope :accepted, where(accepted: true)
You get what you want by #user.sent_invitations.accepted.count
2 . Do the following query
User.where(email: #user.sent_invitations.map(&:recipient_email)).count

Related

Rails - Creating a belongs_to association between models prevents me from editing the model

I'm trying to create an association between two models in my Rails app (User and Coin) where Coin belongs_to User and User has_many Coins. When I add the belongs_to association in the Coin model, I am no longer able to edit or create Coin pages. Why would it do this? As soon as I remove the association, I'm able to create/edit again. Also, the corresponding has_many association on the User page does not have the same effect. I'd appreciate any help in understanding what is happening here and how I can properly make this association. Thanks.
User.rb
class User < ApplicationRecord
acts_as_votable
has_many :questions, dependent: :destroy
has_many :events, dependent: :destroy
has_many :links, dependent: :destroy
has_many :posts, dependent: :destroy
has_many :moderated_coins, class_name: "Coin"
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable,
:validatable, authentication_keys: [:login]
validates :username, presence: :true, uniqueness: { case_sensitive: false }
validates_format_of :username, with: /^[a-zA-Z0-9_\.]*$/, :multiline => true
validate :validate_username
def validate_username
if User.where(email: username).exists?
errors.add(:username, :invalid)
end
end
def login=(login)
#login = login
end
def login
#login || self.username || self.email
end
def self.find_for_database_authentication(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:login)
where(conditions.to_h).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
elsif conditions.has_key?(:username) || conditions.has_key?(:email)
where(conditions.to_h).first
end
end
end
Coin.rb
class Coin < ApplicationRecord
validates :currency_name, presence: true
has_many :questions, dependent: :destroy
has_many :events, dependent: :destroy
has_many :links, dependent: :destroy
mount_uploader :picture, PictureUploader
has_and_belongs_to_many :genres
# belongs_to :moderator, class_name: "User". <--- * The problem is here
validate :picture_size
private
def picture_size
if picture.size > 5.megabytes
errors.add(:picture, "Picture must be smalled than 5MB.")
end
end
end
coins_controller.rb
class CoinsController < ApplicationController
load_and_authorize_resource param_method: :question_params
before_action :find_coin, only: [:edit, :update, :destroy ]
before_action :authenticate_user!, except: [:index, :create, :show]
def index
#search = Coin.ransack(params[:q])
#coins = #search.result(distinct: true)
end
def new
#coin = Coin.new
end
def create
#coin = Coin.new(coin_params)
if #coin.save
flash[:success] = "Coin created"
redirect_to #coin
else
render 'new'
end
end
def show
#coin = Coin.find(params[:id])
end
def edit
authorize! :update, #coin
end
def update
if #coin.update(coin_params)
redirect_to #coin
else
render 'edit'
end
end
def destroy
Coin.find(params[:id]).destroy
redirect_to coins_url
end
private
def coin_params
params.require(:coin).permit( :currency_name, :currency_abbrev, :moderator_id, :accepted, :picture, :question1, :question2, :question3, :question4, genre_ids:[])
end
def find_coin
#coin = Coin.find(params[:id])
end
end
user_controller.rb
class UsersController < ApplicationController
before_action :authenticate_user!
def show
#user = User.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #user }
end
end
end
schema.rb
create_table "coins", force: :cascade do |t|
t.string "link_name"
t.string "currency_name"
t.string "currency_abbrev"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "permalink"
t.boolean "accepted", default: false
t.datetime "accepted_at"
t.string "genre"
t.integer "genre_id"
t.integer "moderator_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.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.string "username"
t.string "wallet"
t.boolean "admin", default: false
t.boolean "moderator", default: false
t.decimal "currentbalance", precision: 8, scale: 2
t.decimal "payout_to_date", precision: 8, scale: 2
t.text "bio"
t.string "link1"
t.string "link2"
t.string "link3"
t.string "link4"
t.string "link5"
t.string "name"
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 ["username"], name: "index_users_on_username", unique: true
end
Use:
belongs_to :moderator, class_name: "User", optional: true
In rails 5, belongs_to enforces existence of the associated record by default. You need to use optional: true in order to allow moderator_id to be nil.

Rails 5 belongs_to weird behaviour

Client Class
class Client < ApplicationRecord
validates_presence_of :name, :email
validates_email_format_of :email, :message => 'is not looking good'
validates_uniqueness_of :email
has_many :projects
end
Project Class
class Project < ApplicationRecord
belongs_to :client, optional: false
validates_presence_of :name
end
And schema of my tables
create_table "clients", force: :cascade do |t|
t.string "name"
t.string "email"
t.string "phone"
t.string "address"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "projects", force: :cascade do |t|
t.string "name"
t.integer "client_id"
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Sometime I want to create Project without having client specified. So I added option :option false. And so now I'm able to create project without specifying any client id. However when I try to create project with client_id, it accepts any value for client_id i.e. if enter 8 and if this id is not present in client then also its accepted. I want in such cases it shouldn't save this project.
How can I achieve this behaviour?
I have rails version 5.1.4
First some changes, is optional: true, optional: false is the default behavior and expects to get a associated record every time, with that said, you could do something like this:
class Project < ApplicationRecord
belongs_to :client, optional: true
# Sorry, small bug, client_id? with value zero would return always false and it becomes zero when you input strings or false
# validates_presence_of :client, if: client_id?
validates_presence_of :client, unless: Proc.new{ |d| d.client_id.blank? }
end
This would validate the client record when the client_id is present
p = Project.new # => #<Project id: nil, client_id: nil, ...
p.valid? # => true
p.client = Client.first # => #Client id: 1, ...
p.valid? # => true
p.client = nil # => nil
p.valid? # => true
#Non-existent id 10
p.client_id = 10 # => 10
p.valid? # => false
p.errors.full_messages # => ["Client can't be blank"]
p.client_id = 1 # => 1
p.client # => #Client id: 1, ...
p.valid? # => true
You can even use a custom message
validates_presence_of :client, message: 'invalid client', if: :client_id?
Finally, just a recommendation, use t.references on your migrations to be able to use foreign keys and get this fields indexed
t.references :client, foreign_key: true
I would write your own custom validation to ensure that the id of the client actually exists in your database before persisting the project record:
class Project < ApplicationRecord
belongs_to :client, optional: false
validates_presence_of :name
validate :validate_client_id, if: :client_id?
private
def validate_client_id
errors.add(:client_id, "is invalid") unless Client.exists?(self.client_id)
end
end
The validation will only run if the field is not blank. Which is convenient since client_id is optional in your case.

How can I move data from one table to another in rails migration?

I have set up a rails site with these resources:
users(devise)
authors
I have realised that I need to move all authors over to users table because I am setting up roles for these users as an author now.
Currently I have tried the following migration but nothing worked and no data was transferred over to the users table:
class MoveAuthorsColumnDataToUsersTable < ActiveRecord::Migration
def change
Author.find_each do |author|
User.find_or_create_by(
:username => author.name.downcase.gsub(' ',''),
:encrypted_password => "",
:email => "",
:avatar_file_name => author.avatar_updated_at,
:avatar_content_type => author.avatar_content_type,
:avatar_file_size => author.avatar_file_size,
:avatar_updated_at => author.avatar_updated_at,
:role_id => "3"
)
end
end
end
I have got an author model setup with attributes in the controller, I am eventually going to transfer all author models relationships to users.
author.rb model:
class Author < ActiveRecord::Base
has_many :books, dependent: :destroy
has_many :ideas, dependent: :destroy
accepts_nested_attributes_for :books
accepts_nested_attributes_for :ideas
validates_uniqueness_of :name
has_attached_file :avatar, :styles => { :large => "980x760", :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end
user.rb model(devise)
class User < ActiveRecord::Base
belongs_to :role
def confirmation_required?
false
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
has_attached_file :avatar, styles: {
large: "600x450#",
medium: "250x250#",
small: "100x100#"
}, :default_url => "/images/:style/filler.png"
#validates_attachment_content_type :avatar, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
validates :avatar, :email, :username, :password, presence: true
end
Here is the schema for users and authors:
create_table "authors", force: true do |t|
t.string "name"
t.text "biography"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "book_id"
t.string "avatar_file_name"
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
t.integer "idea_id"
end
create_table "users", force: true 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"
t.datetime "updated_at"
t.string "avatar_file_name"
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
t.string "username"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.integer "role_id"
end
The end result I am trying to achieve here is to get all authors safely over to users as entries in the postgres database and then from there I can use this data to carry on finishing off what else needs refactoring in the models for users etc.
This will hopefully help someone try and find the right solution to what i am trying to do. I am pretty sure many people have been here before and had the same headache.
Thanks
Assuming:
1.you have created all required column in User table(as it was in author table).
2. You just need to copy all author records to User.
Create your copy_author_to_user.rb file in below location!
# db/scripts/copy_author_to_user.rb
require 'rubygems'
Author.all.each do |a|
user = User.new(
:username => a.name.downcase.strip,
:encrypted_password => '',
:email => '',
:avatar_file_name => a.avatar_updated_at,
:avatar_content_type => a.avatar_content_type,
:avatar_file_size => a.avatar_file_size,
:avatar_updated_at => a.avatar_updated_at,
:role_id => "3"
)
user.save!
end
then from console run :
$rails runner db/scripts/copy_author_to_user.rb
On your user model you have these validations:
validates :avatar, :email, :username, :password, presence: true
However in your migration you're setting encrypted_password to "" which won't pass the presence true validation on password.
As a side note find_or_create_by is going to do 1 of two things, find the first record that matches your hash (username, etc) or if nothing is found create a new use with that info. If you find the record and don't create it, you'll want to call save after the fact.
I like first_or_initialize so something like:
Author.find_each do |author|
user = User.first_or_initialize(
:username => author.name.downcase.gsub(' ',''),
:encrypted_password => "",
:email => "",
:avatar_file_name => author.avatar_updated_at,
:avatar_content_type => author.avatar_content_type,
:avatar_file_size => author.avatar_file_size,
:avatar_updated_at => author.avatar_updated_at,
:role_id => "3"
)
user.save!
end

Single Table Inheritance with Devise in Rails 4

I have read the posts here, here, and here, but I'm still having trouble with implementing Single Table Inheritance.
Ideally I would like to have two registration paths (one for clients and one for providers) with the common fields name, email, password, and confirm_password, and the provider registration having an extra radiobutton field to specify a provider type. I am doing the registration through devise. Upon clicking submit on the registration form a user would then be redirected to a second form which is totally different for clients and providers (I have been doing this using the edit page for a resource).
As it stands, everything works if I am just doing it through User, but as soon as I add single table inheritance the registration forms tell me they are missing the requirements of the second forms.
Here is my config/routes.rb
Rails.application.routes.draw do
devise_for :users, :controllers => {:sessions => "sessions"}, :skip=> :registrations
devise_for :clients, :providers, :skip=> :sessions
resources :clients
resources :providers
root :to=>'pages#home'
match '/home', to: 'pages#home', via: 'get'
end
My models look as follows:
User:
class User < ActiveRecord::Base
before_save {self.email = email.downcase}
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
validates :name, presence: true, length: {maximum: 50}
validates :email, presence: true, :email => {:ban_disposable_email => true, :message => I18n.t('validations.errors.models.user.invalid_email')}, uniqueness: { case_sensitive: false }
validates :password, presence: true, length: {minimum: 6},:if=>:password_validation_required?
LOGO_TYPES = ['image/jpeg', 'image/png', 'image/gif']
has_attached_file :avatar, :styles => {:medium => "300x300>",:square=>"200x200>", :thumb => "100x100>" }, :default_url => '/assets/missing_:style.png'
validates_attachment_content_type :avatar, :content_type => LOGO_TYPES
def password_validation_required?
!#password.blank?
end
end
Client:
class Client < User
validates :industry, presence: true
validates :city, presence: true
validates :state, presence: true
validates :description, presence: true, length: {minimum: 50, maximum: 300}
end
Provider:
class Provider < User
validates :ptype, presence: true
validates :city, presence: true
validates :state, presence: true
validates :education, presence: true
validates :biography, presence:true, length: {minimum: 50, maximum: 300}
validates_format_of :linkedin, :with => URI::regexp(%w(http https))
validates :resume, presence: true
has_many :disciplines
end
and here are my controllers:
class SessionsController < Devise::SessionsController
def create
rtn = super
sign_in(resource.type.underscore, resource.type.constantize.send(:find,resource.id)) unless resource.type.nil?
rtn
end
end
class RegistrationsController < Devise::RegistrationsController
protected
def after_sign_up_path_for(resource)
if resource.is_a?(User)
if current_user.is_a?(Client)
edit_client_path(current_user.id)
elsif current_user.is_a?(Provider)
edit_provider_path(current_user.id)
end
else
super
end
end
end
class ClientsController < ApplicationController
def show
#client = Client.find(params[:id])
end
def edit
#client = Client.find(params[:id])
end
def update
#client = Client.find(params[:id])
if #client.update_attributes(client_params_edit)
flash[:success] = "Profile Updated"
redirect_to #client
else
flash[:failure] = "Profile Information Invalid"
render 'edit'
end
end
def client_params_edit
params.require(:client).permit(:avatar,:industry,:city,:website, :description)
end
end
the provider controller is quite similar.
Finally, here is my schema.rb:
ActiveRecord::Schema.define(version: 20140628213816) do
create_table "disciplines", force: true do |t|
t.integer "years"
t.string "description"
t.integer "user_id"
end
create_table "users", force: true do |t|
t.string "name"
t.string "email"
t.string "avatar_file_name"
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
t.string "password_digest"
t.string "industry"
t.string "city"
t.string "state"
t.string "website"
t.string "description"
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"
t.datetime "updated_at"
t.string "type"
t.string "ptype"
t.string "education"
t.string "resume_file_name"
t.string "resume_content_type"
t.integer "resume_file_size"
t.datetime "resume_updated_at"
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
You need to specify which model should be instantiated inside your custom registrations controller (that one which inherits from Devise::RegistrationsController).
You have to override the protected method called resource_class to somewhat like this:
def resource_class
# for example you pass type inside params[:user]
klass = params[:user].try(:[], :type) || 'Client'
# we don't want wrong class to be instantiated
raise ArgumentError, 'wrong user class' unless ['Client', 'Provider'].include?(klass)
# transform string to class
klass.constantize
end
Also you might want to override sign_up_params to specify allowed params based on user type too.
Just a thought.
Have you considered allowing registration as a user and holding the type parameter back until later in the workflow.
i.e.
Registration page:
Creates User (with a parameter that decides which Type the user will end up being)
Second page (to which you are automatically redirected upon creating user, or even logging in as user having not gone through part 2):
Adds the appropriate required information and changes type from User to your appropriate STI type upon submit.
Other option would be to swap your first "submit" button for a button which simply reveals the relevant extra fields (and the real submit button) via JS.

Creating Associations in Rails using has_many and belongs_to

I know there are a lot of topics on this already but I couldn't find any that were what I'm trying to do. I'm just learning Rails and although I know this is probably a pretty simple fix, I'm stumped.
I'm creating a "Timeline" site. I have user accounts set up, and the user can create timelines. But, what I need to do is associate multiple timeline "events" (items to go in the timeline, the model for these is called Event) with each timeline (the model for which is called Timeline_Object). More plainly - a user has multiple timelines, and a timeline has multiple events.
The problem is that I can't get events set up with the timeline correctly. I think the association is set up correctly between users and timelines, but I'm not completely sure how to figure out what's wrong. Here are my models:
class User < ActiveRecord::Base
has_many :timeline_objects
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation,
:remember_me, :user_name
end
class TimelineObject < ActiveRecord::Base
belongs_to :user
attr_accessible :title, :user_id
has_many :events
end
class Event < ActiveRecord::Base
belongs_to :timeline_object
attr_accessible :date, :description, :time, :title, :image,
:image_width, :image_height, :timeline_objects
has_attached_file :image, :styles => { :large => "500x500>", :medium => "400x400#", :thumb => "100x100>" }
after_post_process :save_image_dimensions
validates :title, presence: true
validates :image, presence: true
validates :time, presence: true
validates :date, presence: true
def save_image_dimensions
geo = Paperclip::Geometry.from_file(image.queued_for_write[:original])
self.image_width = geo.width
self.image_height = geo.height
end
end
After running some migrations to set up the keys in the database, this is what my schema looks like:
ActiveRecord::Schema.define(:version => 20130402144923) do
create_table "events", :force => true do |t|
t.string "title"
t.string "description"
t.string "date"
t.string "time"
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 "image_height"
t.integer "image_width"
t.integer "timeline_objects"
end
add_index "events", ["timeline_objects"], :name => "index_events_on_timeline_objects"
create_table "timeline_objects", :force => true do |t|
t.string "title"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "user_id"
end
add_index "timeline_objects", ["user_id"], :name => "index_timeline_objects_on_user_id"
create_table "users", :force => true do |t|
t.string "user_name"
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
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
When I go to show the timeline (at which point all the events should be displayed), I try to loop through them with
<% #timeline_object.events.each do |event| %>
That line of code produces this error:
SQLite3::SQLException: no such column: events.timeline_object_id: SELECT "events".* FROM "events" WHERE "events"."timeline_object_id" = 4
So I realize that means I'm missing something in my database, but I'm not sure what I should change/add to make it all work.
Let me know if you need any additional info/code. Thanks in advance.
In your Events schema, you have:
t.integer "timeline_objects"
but, it should be:
t.integer "timeline_object_id"
Run a new migration to fix it:
rename_column :events, :timeline_objects, :timeline_object_id
Since each event belongs to a TimelineObject, then it needs a column that identifies the id of the object that it's associated to.

Resources