Rails association user & contacts throwing error - ruby-on-rails

Amended the code base in 'contacts controller' from #contacts = Contact.all to #contacts = current_user.contact so a user can see only their contacts (currently any user sees all the contacts) This is throwing the below error. Tried tweaking but still no success and have checked the database in psql and both have id column. Any ideas or amendment needed in the code?
Failure/Error: <% if #contacts.any? %> ActionView::Template::Error: PG::UndefinedColumn: ERROR: column contacts.user_id does not exist LINE 1: SELECT 1 AS one FROM "contacts" WHERE "contacts"."user_id" ... ^ : SELECT 1 AS one FROM "contacts" WHERE "contacts"."user_id" = $1 LIMIT 1
Contacts Controller
class ContactsController < ApplicationController
before_action :contact, only: [:show, :edit, :update, :destroy] before_action :authenticate_user!
def index
#contacts = current_user.contact end
def new
#contact = Contact.new end
def create
Contact.create(contact_params)
redirect_to '/contacts' end
def show end
def edit end
def update
#contact.update(contact_params)
redirect_to '/contacts/' + "#{#contact[:id]}" end
def destroy
#contact.destroy
redirect_to '/contacts' end
private
def contact_params
params.require(:contact).permit(:firstname, :surname, :email, :phone, :image) end
def contact
#contact = Contact.find(params[:id]) end
end
User controller
class UsersController < ApplicationController
end
Contact model
class Contact < ActiveRecord::Base
belongs_to :user
has_attached_file :image, styles: {thumb: "100x100>"}
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
end
User model
class User < ActiveRecord::Base
has_many :contacts, dependent: :destroy
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
Index html
<%if user_signed_in? %>
<%= link_to 'Log out', destroy_user_session_path, method: :delete %>
<%end%>
<% if #contacts.any? %>
<% #contacts.each do |contact| %>
<%= link_to image_tag(contact.image.url(:thumb)), contact_path(contact) %>
<h3><%= contact.firstname%> <%=contact.surname%></h3>
<%=contact.email%><br />
<%=contact.phone%>
<br />
<br />
<%end%>
<%else%>
No contacts yet!
<%end%>
<br />
<br />
<%= link_to 'Add a contact', new_contact_path%>
Schema
ActiveRecord::Schema.define(version: 20160504125849) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "contacts", force: :cascade do |t|
t.string "firstname"
t.string "surname"
t.string "email"
t.integer "phone"
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.inet "current_sign_in_ip"
t.inet "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, using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
end

Basically you do not have the user_id in the contacts table. That is the foreign key which is used to define a relation to the users. Add the column and then when you create the contact, add the user's id to the user_id column in the contacts table. Then that should work.

Related

Devise Apartment create tenant on or after devise user create

I have a little app that is using devise and apartment gems.
I have User(devise) who has one organization(tenant_name).
The organization has one :owner, class_name 'user'
I want to use the Devise registration form to also create the tenant and assign to the admin.
I think I have read that many tutorials on devise apartment / devise custom controllers / devise nested attributes that I have confused myself.
Registrations form
app/views/devise/registrations/new.html.erb
<div class="row">
<div class="col-lg-4 col-md-6 ml-auto mr-auto">
<h1 class="text-center">Sign Up</h1>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render partial: 'devise/shared/error_messages', resource: resource %>
<div class="form-group">
<%= f.email_field :email, autofocus: false, class: 'form-control', placeholder: "Email Address" %>
</div>
<div class="form-group">
<%= f.simple_fields_for :organizations do |o| %>
<%= o.input :name, placeholder: "Organization Name", warning: "Cant Be Changed", label: false %>
<% end %>
</div>
<div class="form-group">
<%= f.password_field :password, autocomplete: "off", class: 'form-control', placeholder: 'Password' %>
</div>
<div class="form-group">
<%= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control', placeholder: 'Confirm Password' %>
</div>
<div class="form-group">
<%= f.submit "Sign up", class: "btn btn-primary btn-block btn-lg" %>
</div>
<% end %>
<div class="text-center">
<%= render "devise/shared/links" %>
</div>
</div>
</div>
User Model
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_one :organization, dependent: :destroy
after_create :init_organization
accepts_nested_attributes_for :organization
private
def init_organization
self.create_organization!
end
end
Organization Model
class Organization < ApplicationRecord
has_one :owner, class_name: 'User'
has_many :organizations_users
has_many :users, through: :organizations_users
has_many :clients
after_create :create_tenant
def tenant_name
"#{self.id}"
end
private
def create_tenant
Apartment::Tenant.create(self.tenant_name)
end
end
I know that I need to alter my create method on my devise controller so i generated devise custom controllers with from here
rails generate devise:controllers users
and added the custom sanitizers
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]
# GET /resource/sign_up
# def new
# super
# end
# POST /resource
def create
super
end
# GET /resource/edit
# def edit
# super
# end
# PUT /resource
# def update
# super
# end
# DELETE /resource
# def destroy
# super
# end
# GET /resource/cancel
# Forces the session data which is usually expired after sign
# in to be expired now. This is useful if the user wants to
# cancel oauth signing in/up in the middle of the process,
# removing all OAuth session data.
# def cancel
# super
# end
# protected
# If you have extra params to permit, append them to the sanitizer.
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up, keys: [:email, organizations: [:name]])
end
# If you have extra params to permit, append them to the sanitizer.
# def configure_account_update_params
# devise_parameter_sanitizer.permit(:account_update, keys: [:attribute])
# end
# The path used after sign up.
# def after_sign_up_path_for(resource)
# super(resource)
# end
# The path used after sign up for inactive accounts.
# def after_inactive_sign_up_path_for(resource)
# super(resource)
# end
end
schema
ActiveRecord::Schema.define(version: 2019_05_12_083957) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
enable_extension "uuid-ossp"
create_table "Organizations_Users", id: false, force: :cascade do |t|
t.uuid "Organization_id", null: false
t.uuid "User_id", null: false
end
create_table "clients", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "name"
t.uuid "organization_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["organization_id"], name: "index_clients_on_organization_id"
end
create_table "equipment", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "name"
t.uuid "site_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["site_id"], name: "index_equipment_on_site_id"
end
create_table "organizations", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.uuid "user", null: false
end
create_table "sites", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "name"
t.uuid "client_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["client_id"], name: "index_sites_on_client_id"
end
create_table "users", id: :uuid, default: -> { "gen_random_uuid()" }, 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.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 "clients", "organizations"
add_foreign_key "equipment", "sites"
add_foreign_key "sites", "clients"
end
when i go through the sign up process i get unknown attribute 'organizations' for User.
Update:
I added two new migration to add reference to user on the organization, and organization to the user.
I did this to create the association for the owner, should i have called the reference owner
class AddUserToOrganization < ActiveRecord::Migration[5.2]
def change
add_reference :organizations, :user, type: :uuid, null: false, index: true, foreign_key: true
end
end
class AddOrganizationToUser < ActiveRecord::Migration[5.2]
def change
add_reference :users, :organization, type: :uuid, null: false, index: true, foreign_key: true
end
end
My Schema now looks like so:
ActiveRecord::Schema.define(version: 2019_05_13_223120) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
enable_extension "uuid-ossp"
create_table "Organizations_Users", id: false, force: :cascade do |t|
t.uuid "Organization_id", null: false
t.uuid "User_id", null: false
end
create_table "clients", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "name"
t.uuid "organization_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["organization_id"], name: "index_clients_on_organization_id"
end
create_table "equipment", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "name"
t.uuid "site_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["site_id"], name: "index_equipment_on_site_id"
end
create_table "organizations", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.uuid "user_id", null: false
t.index ["user_id"], name: "index_organizations_on_user_id"
end
create_table "sites", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "name"
t.uuid "client_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["client_id"], name: "index_sites_on_client_id"
end
create_table "users", id: :uuid, default: -> { "gen_random_uuid()" }, 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.uuid "organization_id", null: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["organization_id"], name: "index_users_on_organization_id"
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
add_foreign_key "clients", "organizations"
add_foreign_key "equipment", "sites"
add_foreign_key "organizations", "users"
add_foreign_key "sites", "clients"
add_foreign_key "users", "organizations"
end
I followed the direction from to change my user/ registrations controller to :
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]
def new
super
#organization = Organization.new
end
# POST /resource
def create
super
end
# GET /resource/edit
# def edit
# super
# end
# PUT /resource
# def update
# super
# end
# DELETE /resource
# def destroy
# super
# end
# GET /resource/cancel
# Forces the session data which is usually expired after sign
# in to be expired now. This is useful if the user wants to
# cancel oauth signing in/up in the middle of the process,
# removing all OAuth session data.
# def cancel
# super
# end
# protected
# If you have extra params to permit, append them to the sanitizer.
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up, keys: [:email, organizations: [:name]])
end
# If you have extra params to permit, append them to the sanitizer.
# def configure_account_update_params
# devise_parameter_sanitizer.permit(:account_update, keys: [:attribute])
# end
# The path used after sign up.
# def after_sign_up_path_for(resource)
# super(resource)
# end
# The path used after sign up for inactive accounts.
# def after_inactive_sign_up_path_for(resource)
# super(resource)
# end
end
and my form now
<%= simple_form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => {:class => 'form-horizontal' }) do |f| %>
<%= render partial: 'devise/shared/error_messages', resource: resource %>
<%= f.input :email, autofocus: false, class: 'form-control', placeholder: "Email Address", label: false %>
<%= f.simple_fields_for :organization do |o| %>
<%= o.input :name, placeholder: "Organization Name", warning: "Cant Be Changed", label: false %>
<% end %>
<%= f.input :password, autocomplete: "off", class: 'form-control', placeholder: 'Password', label: false %>
<%= f.input :password_confirmation, autocomplete: "off", class: 'form-control', placeholder: 'Confirm Password', label: false %>
<%= f.button :submit, "Sign up", class: "btn btn-primary btn-block btn-lg" %>
<% end %>
my problem now is that i cannot see the organization name field in the view of the form.
In has_one relation you should use the singular form:
<div class="form-group">
<%= f.simple_fields_for :organization do |o| %>
<%= o.input :name, placeholder: "Organization Name", warning: "Cant Be Changed", label: false %>
<% end %>
</div>
I think the rest of your code should work as is!
Edit: how to instantiate a new org
You indicated that the form is empty, that's because there is no org instance. Do the following in your user controller:
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]
GET /resource/sign_up
def new
super
#user.organization = Organization.new
end
# POST /resource
def create
super
end
end

Rails searching a has_many relationship

Heyo. Been trying to figure this out but I've been stuck too long and it's just getting painful!
I'm trying to do an Advanced Search form allowing you to search for Users based off settings that are in other models. e.g. Search for a User named Jim, who does Running, and has weight loss as his goal.
I have three models:
User (using Devise)
Sport (many-to-many with user)
Goals (user has_many goals, goal belongs_to user)
So far I have managed to get it working so I can search for things in the User model (such as name) and also for Users Sports through a select box. What I haven't been able to get working is searching for the Users goals and I don't get why.
What I get is "Nobody seems to have these preferences" when searching ONLY for Goals and no other fields.
I have tried using the same code as my Sports but that didn't work (guessing because of the different relationships?)
# searches/show.html.erb
<% if #search.search_users.empty? %>
<p>Nobody seems to have these preferences</p>
<% else %>
<% #search.search_users.each do |u| %>
<tr>
<td><%= u.name %></td>
<% u.sports.each do |s| %>
<td><%= s.name %></td>
<% end %>
<% u.goals.each do |g| %>
<td><%= g.name %></td>
<% end %>
</tr>
<% end %>
I've done associations in the console and when I type for example u.goals I get this (and the opposite when I query what users are associated with a goal):
irb(main):015:0> u.goals
=> #<ActiveRecord::Associations::CollectionProxy [#<Goal id: 1, name: "Weight Loss", user_id: 1>, #<Goal id: 3, name: "Strength", user_id: 1>]>
Here's my current code:
# user.rb
class User < ApplicationRecord
has_and_belongs_to_many :sports
has_many :goals, :foreign_key => :goal_id
end
# sport.rb
class Sport < ApplicationRecord
has_and_belongs_to_many :users
end
# goal.rb
class Goal < ApplicationRecord
belongs_to :user, :foreign_key => :goal_id
end
And my searches stuff:
# search.rb
def search_users
users = User.all
users = users.where("users.name ILIKE ?", "%#{keywords}%") if keywords.present?
users = users.joins(:sports).where("sports.name ILIKE ?", "%#{name}%") if name.present?
users = users.where(goal_id: goal_id) if goal_id.present?
return users
end
# searches/new.html.erb
<%= form_for #search do |s| %>
<div class="form-group">
<%= s.label :keywords %>
<%= s.text_field :keywords %>
</div>
<div class="form-group">
<%= s.label :exercise %>
<%= s.select :name, options_for_select(#s_names), include_blank: true %>
</div>
<div class="form-group">
<%= s.label :goals %>
<%= s.collection_select :goal_id, Goal.order(:name), :id, :name, include_blank: true %>
</div>
<%= s.submit "Search", class: "btn btn-primary" %>
<% end %>
# searches_controller.rb
class SearchesController < ApplicationController
def new
#search = Search.new
#s_names = Sport.uniq.pluck(:name)
#users = User.uniq.pluck(:name)
end
def create
#search = Search.create(search_params)
redirect_to #search
end
def show
#search = Search.find(params[:id])
end
private
def search_params
params.require(:search).permit(:keywords, :name, :goal_id)
end
end
and then my schema for reference:
create_table "goals", force: :cascade do |t|
t.string "name"
t.integer "user_id"
t.index ["user_id"], name: "index_goals_on_user_id", using: :btree
end
create_table "searches", force: :cascade do |t|
t.string "keywords"
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "goal_id"
t.index ["goal_id"], name: "index_searches_on_goal_id", using: :btree
end
create_table "sports", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "sports_users", id: false, force: :cascade do |t|
t.integer "user_id", null: false
t.integer "sport_id", null: false
t.index ["user_id", "sport_id"], name: "index_sports_users_on_user_id_and_sport_id", using: :btree
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.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name"
t.integer "movement_id"
t.integer "goal_id"
t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
t.index ["goal_id"], name: "index_users_on_goal_id", using: :btree
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
end
add_foreign_key "goals", "users"
end
Extremely sorry for the huge amount of messy code but I'm just tripping over myself at this point and getting confused.
Thank you greatly in advance.
I would change
users = users.where(goal_id: goal_id) if goal_id.present?
To
users = users.joins(:goals).where(goals: {id: goal_id})
For advanced searching I've recently used approach presented in this article: http://www.justinweiss.com/articles/search-and-filter-rails-models-without-bloating-your-controller/ and I think it's worth reading if you think about expanding search options.
EDIT: full response in comments below
:foreign_key => :goal_id needed to be removed

Ruby on Rails Params set recipient and sender with users_id

Have a recipient and sender, both of the same class(Message) for a messaging system in rails. Want to set the params for both i.e. if user creates a message sender by default is the user_id and recipient will be the contact selected from the users contact list.
Currently the database is only receiving a user_id to the recipient_id column which is wrong and should be to sender_id column. Sender_id receives nothing.
After reading, some say not to amend the params as this is bad practice. So set a hidden field in the message view (like the body and title) yet this isn't pushing in to the database.
Two questions, is this process an appropriate rails practice? (ask this as new to rails) If not: can you advise another path or direction? If so: any ideas/thoughts why this isn't saving in to the database?
user model
class User < ActiveRecord::Base
has_many :messages, class_name: "Message", foreign_key: "recipient_id"
has_many :sent_messages, class_name: "Message", foreign_key: "sender_id"
has_many :contacts, dependent: :destroy
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
validates_presence_of :firstname, allow_blank: false
validates_presence_of :surname, allow_blank: false
end
message model
class Message < ActiveRecord::Base
belongs_to :sender, class_name: "User", foreign_key: "sender_id"
belongs_to :recipient, class_name: "User", foreign_key: "recipient_id"
validates_presence_of :body, :title
end
Messages controller
class MessagesController < ApplicationController
before_action :message, only: [:show]
before_action :authenticate_user!
def index
#messages = current_user.messages
end
def new
#message = Message.new
end
def create
current_user.messages.create(message_params)
redirect_to '/messages'
end
def show
end
private
def message_params
params.require(:message).permit(:title, :body, :sender_id, :recipient_id)
end
def message
#message = Message.find(params[:id])
end
end
message/new view
<%= form_for #message do |f| %>
<%= hidden_field_tag :sender_id, current_user.id %>
<%= f.text_field :title %>
<%= f.text_field :body %>
<%= f.submit %>
<% end %>
schema
ActiveRecord::Schema.define(version: 20160517131719) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "contacts", force: :cascade do |t|
t.string "firstname"
t.string "surname"
t.string "email"
t.integer "phone"
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 "user_id"
end
add_index "contacts", ["user_id"], name: "index_contacts_on_user_id", using: :btree
create_table "messages", force: :cascade do |t|
t.string "title"
t.text "body"
t.integer "sender_id"
t.integer "recipient_id"
t.datetime "created_at"
t.datetime "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.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "firstname"
t.string "surname"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
add_foreign_key "contacts", "users"
end
Try changing your form to this:
<%= form_for #message do |f| %>
<%= f.hidden_field :sender_id, value: current_user.id %>
<%= f.text_field :title %>
<%= f.text_field :body %>
<%= f.submit %>
<% end %>
Currently the database is only receiving a user_id to the recipient_id
column which is wrong and should be to sender_id column.
In your create action, you have current_user.messages.create(message_params). This creates a message record in the DB with the foreign key's(i.e, recipient_id in your case) value with the parent's(user) id. This is the reason, the recipient_id gets the value of user's id.
Sender_id receives nothing.
This is because the hidden_field set for sender_id is not wrapped with the form builder instance. You need to change
<%= hidden_field_tag :sender_id, current_user.id %>
to
<%= f.hidden_field :sender_id, current_user.id %>

Rails Issues with association between User and Contact

Initially started with Contacts, as expected created a list of populated contacts which correctly allow CRUD. Then set up the login with devise which created Users. When logging in as two different users each should only see their own contacts however currently users sees all the same contacts.
Any help resolving this issue would be appreciated?
(Not sure if should have started with User and then created Contact, feels like this is created backwards.)
Understanding for associations is User 'has_many :contacts' and Contacts 'belongs_to :users' have been changing and spiking to no avail.
ContactsController
class ContactsController < ApplicationController
before_action :contact, only: [ :show, :edit, :update, :destroy] before_action :authenticate_user!
def index
#contacts = Contact.all end
def new
#contact = Contact.new end
def create
Contact.create(contact_params)
redirect_to '/contacts' end
def show end
def edit end
def update
#contact.update(contact_params)
redirect_to '/contacts/' + "#{#contact[:id]}" end
def destroy
#contact.destroy
redirect_to '/contacts' end
private
def contact_params
params.require(:contact).permit(:firstname, :surname, :email, :phone, :image) end``
def contact
#contact = Contact.find(params[:id]) end
end
UsersController
class UsersController < ApplicationController
end
model Contact
class Contact < ActiveRecord::Base
belongs_to :users
has_attached_file :image, styles: {thumb: "100x100>"}
validates_attachment_content_type :image, content_type:
/\Aimage\/.*\Z/
end
model user
class User < ActiveRecord::Base has_many :contacts, dependent: :destroy devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable end
indexhtml
<%if user_signed_in? %> <%= link_to 'Log out', destroy_user_session_path, method: :delete %> <%end%>
<% if #contacts.any? %> <% #contacts.each do |contact| %> <%= link_to image_tag(contact.image.url(:thumb)), contact_path(contact) %> <h3><%= contact.firstname%> <%=contact.surname%></h3> <%=contact.email%><br /> <%=contact.phone%> <br /> <br /> <%end%> <%else%> No contacts yet! <%end%> <br /> <br /> <%= link_to 'Add a contact', new_contact_path%>
show html
<p><%= image_tag #contact.image.url(:thumb) %></p> <p><%= #contact.firstname %> <%= #contact.surname %></p> <p><%= #contact.phone %></p> <p><%= #contact.email %></p>
<%= link_to 'Edit', edit_contact_path(#contact) %> <%= link_to 'Remove', contact_path(#contact), method: :delete %><br /><br /> <%= link_to 'Contacts', contacts_path %>
schema
ActiveRecord::Schema.define(version: 20160504125849) do
# These are extensions that must be enabled in order to support this database enable_extension "plpgsql"
create_table "contacts", force: :cascade do |t|
t.string "firstname"
t.string "surname"
t.string "email"
t.integer "phone"
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.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false end
When logging in as two different users each should only see their own
contacts however currently users sees all the same contacts
The problem is with this line #contacts = Contact.all. It holds all the contacts. As you want to display only the current_user's contacts, you just need it to below
#contacts = current_user.contacts
ActionView::Template::Error: PG::UndefinedColumn: ERROR: column
contacts.user_id does not exist LINE 1: SELECT 1 AS one FROM
"contacts" WHERE "contacts"."user_id" ... ^ : SELECT 1 AS one FROM
"contacts" WHERE "contacts"."user_id" = $1 LIMIT 1
It seems the contacts table doesn't have user_id column. Create a new migration to add the same and do rake db:migrate

adding a foreign key in the table

I keep getting this exception: "SQLite3::SQLException: no such column: books.user_id: SELECT "books".* FROM "books" WHERE ("books".user_id = 4)". Which sounds like there is no user_id in the books table.
So I just installed the Foreigner plugin and added "t.integer :user_id, :null => false" and "add_foreign_key(:books, :users)" in the book migration file. I ran "rake db:migrate", but still it is giving me the same exception.
I am using Rails 3 in Windows and Devise to authenticate user.
HOME VIEW
<p><%= link_to "Add new Book",:controller =>"book", :action => 'new' %></p>
<% #books.each do |b| %>
<p><%= b.author%></p>
<p><%= b.title%></p>
<%end%>
HOME CONTROLLER
class HomeController < ApplicationController
def index
#user = current_user
#user.books||=Book.new
#books=#user.books
end
end
BOOK CONTROLLER
class BookController < ApplicationController
def new
#books = Book.new
# redirect_to :controller=>"home" ,:action=>"index"
end
def create
#books = Book.new(params[:book])
if #books.save
render "home/index"
#redirect_to :controller=>"home" ,:action=>"index"
else
render :action => 'new'
end
end
CREATE TABLE/BOOK MIGRATION
class CreateBooks < ActiveRecord::Migration
def self.up
create_table :books do |t|
t.text :title
t.text :author
t.integer :user_id, :null => false
t.timestamps
end
add_foreign_key(:books, :users)
end
BOOK VIEW
<h1>Book#new</h1>
<%= form_for(:book) do |f| %>
<p><%= f.text_field :title %></p>
<p><%= f.text_field :author %></p>
<p><%= f.submit "Add book"%>
BOOK MODEL
class Book < ActiveRecord::Base
belongs_to :user
end
USER MODEL
class User < ActiveRecord::Base
has_many :books
# Include default devise modules. Others available are:
# :token_authenticatable, :lockable, :timeoutable and :activatable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation,:firstname,:lastname,:school,:major,:sex,:zipcode
end
ROUTE
Campus::Application.routes.draw do
get "book/index"
get "book/edit"
get "book/new"
get "home/edit"
devise_for :users
resources :book
root :to=> "home#index"
match '/book/new' =>"home#index"
end
DATABASE SCHEMA
ActiveRecord::Schema.define(:version => 20110609055608) do
create_table "books", :force => true do |t|
t.text "title"
t.text "author"
t.integer "user_id", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "courses", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "strong_ins", :force => true do |t|
t.string "subject"
t.string "topic"
t.text "description"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", :force => true do |t|
t.string "email", :default => "", :null => false
t.string "encrypted_password", :limit => 128, :default => "", :null => false
t.string "password_salt", :default => "", :null => false
t.string "reset_password_token"
t.string "remember_token"
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"
t.datetime "updated_at"
t.string "firstname"
t.string "lastname"
t.text "school"
t.text "major"
t.string "sex"
t.integer "zipcode"
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
create_table "weak_ins", :force => true do |t|
t.string "subject"
t.string "topic"
t.text "description"
t.datetime "created_at"
t.datetime "updated_at"
end
end
The user_id column should appear in the schema after running the migration. It's not in your listing, so I'd say that's the problem. Make sure rake db:migrate is completing without errors. You can redo the migration with rake db:rollback && rake db:migrate, if necessary.

Resources