Saving Signature Pad JSON in Rails Database - ruby-on-rails
I'm using the wonderful Thomas Bradley Signature Pad plugin but having some issues saving the JSON signature to my users table (PSQL).
Here's relevant user controller actions:
def edit
#user = current_user
end
def update
#user = current_user
if #user.update_attributes(user_params)
redirect_to dashboard_path
else
render :edit
end
end
protected
def user_params
params.require(:user).permit(
:first_name, :last_name, :phone, :email, :password_digest, :address, :city, :province, :signature)
end
Here's my form:
<%= form_for #user, :html => {:class => "signature"} do |f| %>
<div class="form-group" style="width:205px; height: 60px;">
<%= f.label :signature, "Signature" %>
<ul class="sigNav">
<li class="clearButton">Clear</li>
</ul>
<div class="sig sigWrapper">
<div class="typed"></div>
<canvas class="pad" width="200" height="53"></canvas>
<%= f.hidden_field :signature, :class=>"output", :name=>"output" %>
</div>
</div>
<div class="spacer clearfix"></div>
<div class="form-group">
<%= f.submit "Save", :class=>"btn btn-primary" %>
</div>
<% end %>
<script>
$(document).ready(function () {
$('.signature').signaturePad({drawOnly:true});
});
</script>
When I save the form, I get no errors but the singature JSON isn't saved. No errors in the log either. When I binding.pry, I can see all the params are going through except when I type user_params, the signature is not showing up..
Anything obviously wrong in my code?
EDIT: Adding User Model, User Schema, and Log:
User.rb:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :patients
has_many :assessments, dependent: :destroy
validates :email, presence: true
validates :password, presence: true
end
User Schema:
create_table "users", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.string "password_digest"
t.string "phone"
t.string "city"
t.string "postal"
t.string "province"
t.string "address"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
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"
end
LOG when I try to update the User:
Started PATCH "/users/1" for ::1 at 2015-05-28 13:53:39 -0700
Processing by UsersController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ZbHqJwkOAZdYwAsTBFPIINE38uwidtUevU2/bWmgeBenXGViy3gDRbj1m5Oe3OUEWa1JkNGFHMRb4sMNnidt0A==", "user"=>{"first_name"=>"Jackson", "last_name"=>"", "email"=>"jackson#gmail.com", "phone"=>"", "address"=>"", "city"=>"", "province"=>""}, "signature"=>"[{\"lx\":52,\"ly\":27,\"mx\":52,\"my\":26},{\"lx\":51,\"ly\":26,\"mx\":52,\"my\":27},{\"lx\":47,\"ly\":28,\"mx\":51,\"my\":26},{\"lx\":38,\"ly\":32,\"mx\":47,\"my\":28},{\"lx\":30,\"ly\":34,\"mx\":38,\"my\":32},{\"lx\":20,\"ly\":37,\"mx\":30,\"my\":34},{\"lx\":14,\"ly\":38,\"mx\":20,\"my\":37},{\"lx\":10,\"ly\":39,\"mx\":14,\"my\":38},{\"lx\":9,\"ly\":39,\"mx\":10,\"my\":39},{\"lx\":11,\"ly\":34,\"mx\":9,\"my\":39},{\"lx\":15,\"ly\":27,\"mx\":11,\"my\":34},{\"lx\":20,\"ly\":18,\"mx\":15,\"my\":27},{\"lx\":27,\"ly\":11,\"mx\":20,\"my\":18},{\"lx\":34,\"ly\":5,\"mx\":27,\"my\":11},{\"lx\":41,\"ly\":0,\"mx\":34,\"my\":5},{\"lx\":46,\"ly\":-2,\"mx\":41,\"my\":0},{\"lx\":50,\"ly\":3,\"mx\":50,\"my\":2},{\"lx\":50,\"ly\":14,\"mx\":50,\"my\":3},{\"lx\":50,\"ly\":31,\"mx\":50,\"my\":14},{\"lx\":50,\"ly\":42,\"mx\":50,\"my\":31},{\"lx\":50,\"ly\":51,\"mx\":50,\"my\":42},{\"lx\":50,\"ly\":58,\"mx\":50,\"my\":51},{\"lx\":53,\"ly\":50,\"mx\":53,\"my\":49},{\"lx\":54,\"ly\":43,\"mx\":53,\"my\":50},{\"lx\":58,\"ly\":36,\"mx\":54,\"my\":43},{\"lx\":63,\"ly\":28,\"mx\":58,\"my\":36},{\"lx\":67,\"ly\":21,\"mx\":63,\"my\":28},{\"lx\":70,\"ly\":17,\"mx\":67,\"my\":21},{\"lx\":72,\"ly\":15,\"mx\":70,\"my\":17},{\"lx\":73,\"ly\":13,\"mx\":72,\"my\":15},{\"lx\":74,\"ly\":13,\"mx\":73,\"my\":13},{\"lx\":75,\"ly\":11,\"mx\":74,\"my\":13},{\"lx\":75,\"ly\":14,\"mx\":75,\"my\":11},{\"lx\":75,\"ly\":24,\"mx\":75,\"my\":14},{\"lx\":74,\"ly\":36,\"mx\":75,\"my\":24},{\"lx\":72,\"ly\":47,\"mx\":74,\"my\":36},{\"lx\":71,\"ly\":56,\"mx\":72,\"my\":47},{\"lx\":57,\"ly\":50,\"mx\":57,\"my\":49},{\"lx\":51,\"ly\":41,\"mx\":57,\"my\":50},{\"lx\":45,\"ly\":37,\"mx\":51,\"my\":41},{\"lx\":39,\"ly\":31,\"mx\":45,\"my\":37},{\"lx\":36,\"ly\":29,\"mx\":39,\"my\":31},{\"lx\":33,\"ly\":26,\"mx\":36,\"my\":29},{\"lx\":32,\"ly\":23,\"mx\":33,\"my\":26},{\"lx\":31,\"ly\":21,\"mx\":32,\"my\":23},{\"lx\":30,\"ly\":19,\"mx\":31,\"my\":21},{\"lx\":34,\"ly\":19,\"mx\":30,\"my\":19},{\"lx\":40,\"ly\":19,\"mx\":34,\"my\":19},{\"lx\":47,\"ly\":19,\"mx\":40,\"my\":19},{\"lx\":63,\"ly\":19,\"mx\":47,\"my\":19},{\"lx\":78,\"ly\":20,\"mx\":63,\"my\":19},{\"lx\":90,\"ly\":21,\"mx\":78,\"my\":20},{\"lx\":98,\"ly\":21,\"mx\":90,\"my\":21},{\"lx\":104,\"ly\":21,\"mx\":98,\"my\":21},{\"lx\":106,\"ly\":21,\"mx\":104,\"my\":21}]", "commit"=>"Save", "id"=>"1"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
(0.2ms) BEGIN
(0.2ms) ROLLBACK
Rendered users/edit.html.erb within layouts/application (2.8ms)
Rendered layouts/_nav.html.erb (1.3ms)
Rendered layouts/_flash_messages.html.erb (0.1ms)
Completed 200 OK in 651ms (Views: 644.3ms | ActiveRecord: 0.9ms)
#TomDalling solved the issue for me. Turned out to be a really simple issue when I was submitting the data.
Save a JSON array to database in rails with strong_params
It's because output is not inside the user attributes. You have:
{
"first_name" => "Jackson",
"last_name" => "Cunningham",
// etc.
},
"output" => "asasfafsafs"
But what you actually want is:
{
"first_name" => "Jackson",
"last_name" => "Cunningham",
"output" => "asasfafsafs",
// etc.
}
So in your HTML form, then name should be <input name="user[output]"> instead of <input name="output">.
Related
Role is not being added to users in database
I've been having issues creating separate users for my rails web application. Today I tried to follow Zhurora's answer to a similar post. https://stackoverflow.com/a/32159123 However now when users are signing up on the signup page, and select a role from the options, that role does not get written into the database. I had set up the migrations as instructed and when I check the schema it has an entry for role. However it still doesnt get added. This is what happens in the terminal when a user signs up after selecting a role. Started POST "/users" for 127.0.0.1 at 2018-04-07 19:54:54 +0200 Processing by RegistrationsController#create as HTML Parameters: {"utf8"=>"✓","authenticity_token"=>"XKuxBEDRnYGOMMJXP1hb8HfkHkVc4WrMddq13WCqnXW//g6R+yzZ7DB8NTBkDgKsJReIcg83gkmfYaTEpmq+iQ==", "user"=>{"name"=>"gdfgdfg", "email"=>"Mytest#Mytest.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "role"=>"restaurant"}, "commit"=>"Sign up"} Unpermitted parameter: :role (0.1ms) BEGIN User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "mytest#mytest.com"], ["LIMIT", 1]] SQL (0.3ms) INSERT INTO "users" ("name", "email", "encrypted_password", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["name", "gdfgdfg"], ["email", "mytest#mytest.com"], ["encrypted_password", "$2a$11$4qjIxrh1RO.CL7FEPoVFs.xa712fALq4ayFMIC/8taGmU6iUWRphe"], ["created_at", "2018-04-07 17:54:54.479270"], ["updated_at", "2018-04-07 17:54:54.479270"]] (428.6ms) COMMIT And here is my user.rb model class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable enum role: {person: 0, restaurant: 1, admin: 2} has_many :posts, dependent: :destroy validates :role, presence: true validates :name, presence: true, length: { minimum: 4 } validates :password, presence: true, length: { minimum: 5 } validates :password_confirmation, presence: true, length: { minimum: 5 } end My schema.rb file with the user table create_table "users", force: :cascade do |t| t.string "name", default: "", null: false 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.integer "role" 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 The migration file class AddRoleToUsers < ActiveRecord::Migration[5.1] def change add_column :users, :role, :integer end end And my signup html.erb page <%= bootstrap_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %> <%= f.text_field :name, placeholder: 'username (will be shown publicly)', class: 'form-control' %> <%= f.text_field :email, placeholder: 'email', class: 'form-control' %> <%= f.password_field :password, placeholder: 'password', class: 'form-control' %> <%= f.password_field :password_confirmation, placeholder: 'password confirmation', class: 'form-control' %> <%= f.select :role, collection: User.roles.keys.to_a %> <%= f.submit 'Sign up', class: 'btn sign-up-button' %> <% end %> In my attempt to fix it, I have dropped all the tables, thinking it wasnt getting updated in postgresql properly. Recreated the tables and run the migrations through again. I have also deleted the schema file and ran the migrations again generating a new schema file. None of that has worked. Any help would be appreciated. Thank you very much
you need to permit additional parameters class ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? protected def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:role]) end end
Thanks to Mezbah I looked into adding role to the permitted parameters. I was blinded and overlooked that. I overrided the registrations controller with my own class RegistrationsController < Devise::RegistrationsController private def sign_up_params params.require(:user).permit( :name, :email, :password, :password_confirmation) end def account_update_params params.require(:user).permit( :name, :email, :password, :password_confirmation, :current_password) end end This is how it looked before. And based on what Mezbah said, I added it to here class RegistrationsController < Devise::RegistrationsController private def sign_up_params params.require(:user).permit( :name, :email, :password, :password_confirmation, :role) end def account_update_params params.require(:user).permit( :name, :email, :password, :password_confirmation, :current_password) end end And now it works :D Here is a successful entry into the database Started POST "/users" for 127.0.0.1 at 2018-04-07 22:45:24 +0200 Processing by RegistrationsController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"ccL1AgCfT8WfRv7ObfF3INJ8bNcpQ1/WVDBxtX3CAUAW1Qsq+T3ndoYGMikOgrkWuUZmA9vtv2FS70+zTnwzmw==", "user"=>{"name"=>"MyTest", "email"=>"Mytest#Mytest.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "role"=>"restaurant"}, "commit"=>"Sign up"} (0.1ms) BEGIN User Exists (0.3ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "mytest#mytest.com"], ["LIMIT", 1]] SQL (0.3ms) INSERT INTO "users" ("name", "email", "encrypted_password", "created_at", "updated_at", "role") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["name", "MyTest"], ["email", "mytest#mytest.com"], ["encrypted_password", "$2a$11$isG5sdUAJmmtKCcgt4oZ1.HP6IPT4F2oPOFWWMi.raYJLsbuhcnPC"], ["created_at", "2018-04-07 20:45:24.216616"], ["updated_at", "2018-04-07 20:45:24.216616"], ["role", 1]] (19.3ms) COMMIT
Rails rolling back twice every time I try to post Data
I am trying to create an app that allows users to make lists of items and view only the lists they themselves have created. Every time I press submit on the form this happens Started POST "/lists" for 127.0.0.1 at 2017-08-18 15:56:40 -0400 Processing by ListsController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"VnsMdQq3mw5XabkYCZFTgvgwFc3H89paHA0VE5gunFbiMfa0xGr0p1GEZDHc3yemwBx07K1h4CXuS0l5XL1VbA==", "list"=>{"income"=>"12", "put_into_savings"=>"12", "month"=>"12", "year"=>"21"}, "commit"=>"Create List"} (0.1ms) begin transaction (0.1ms) rollback transaction (0.0ms) begin transaction (0.0ms) rollback transaction Rendering lists/new.html.erb within layouts/application Rendered lists/new.html.erb within layouts/application (9.3ms) User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 5], ["LIMIT", 1]] Completed 200 OK in 269ms (Views: 222.2ms | ActiveRecord: 2.7ms) Here is all my code: lists_controller.rb class ListsController < ApplicationController def show #user = User.find(params[:id]) #lists = #user.lists end def new end def edit end def create #list = List.create(list_params) if #list.save redirect_to home_url else render :new end end private def list_params params.require(:list).permit(:income, :put_into_savings, :month, :year) end end lists/new.html.erb <%= form_for List.new do |f| %> <div class="field"> <%= f.label :income %><br /> <%= f.text_field :income %> </div> <div class="field"> <%= f.label :put_into_savings %><br /> <%= f.text_area :put_into_savings %> </div> <div class="field"> <%= f.label :month %><br /> <%= f.number_field :month %> </div> <div class="field"> <%= f.label :year %><br /> <%= f.number_field :year %> </div> <div class="actions"> <%= f.submit %> </div> <% end %> schema.rb ActiveRecord::Schema.define(version: 20170818185700) do create_table "items", force: :cascade do |t| t.string "item_name" t.integer "item_cost" t.string "item_waste" t.string "item_group" t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "lists", force: :cascade do |t| t.integer "income" t.integer "put_into_savings" t.string "month" t.string "year" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "Item_id" t.integer "User_id" end create_table "users", force: :cascade do |t| t.string "email" t.string "password_digest" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.string "name" end end Routes.rb Rails.application.routes.draw do root 'home#index' get 'home' => 'home#index' resources :lists resources :sessions, only: [:new, :create, :destroy] resources :users, only: [:new, :create] # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end Here is my list model: class List < ApplicationRecord has_many :items belongs_to :user end How can I solve this?
You are having logic problem with your model association. Assuming that a List could have more than one Item, you shouldn't have declared your table List with the attribute item_id. (Doing that it means a List could ONLY have one item). I recommend you read ruby-on-rais-guide-for-associations. For the problem with the user_id, you need to explicit declared the user_id in your list object (considering that you want to associate a List with a User in the moment the List is created). One way to do it could be: def create #list = List.new(list_params) #list[:user_id] = current_user.id # Considering you add this method if #list.save redirect_to home_url else render :new end And add some validation in model: class List < ApplicationRecord has_many :items belongs_to :user validates :user_id, presence: true end It seems you need to read more about validation too ruby-on-rais-guide-for-validation. About your twice rollback, it is unclear the reason, but fixing you association and validations problems, I think you can fix it. Try read more about rails, the problem you are having are really basic. Good luck! UPDATE: As suggested by at0misk answer, to solve the problem with twice rollback: In List controller: #list = List.new(list_params) # instead of #list = List.create(list_params) The create method create a new object and save immediately. So, rails was trying to save twice, in the method create first, then in the method save in sequence.
In your create method, you're calling create and then calling save. Create creates an object and saves it to the database, so calling save is redundent. Have you checked to see if your record is saving? If it is then this is definitely what's wrong. I prefer to use this pattern, using new instead of create, and then attempting to save in an if block: def create #list = List.new(list_params) if #list.save redirect_to home_url else render :new end end
Rails: Create action not saving has_many through associations - "rollback transaction"
Be easy on me, I'm just starting to learn Rails and this is my first question on here! The project I'm using to learn is a volleyball scoreboard, so right now I'm trying to build a form that will submit the score of a 2v2 game. I have users and games which are associated by a has_many through relationship to a join table of participants which also includes a 'result' attribute ('W' or 'L'). My problem is that when I submit it fails, and no participants are created. If I removed the associations from the form, submission will work with just game parameters. Hopefully, I've included all the relevant information below. Also, if there is a better way to do all this, I'd love to hear it! MODELS class Game < ApplicationRecord has_one :venue has_many :participants has_many :users, through: :participants accepts_nested_attributes_for :participants, reject_if: :all_blank, allow_destroy: true end class User < ApplicationRecord has_many :participants has_many :games, through: :participants end class Participant < ApplicationRecord belongs_to :game belongs_to :user end SCHEMA create_table "games", force: :cascade do |t| t.date "game_date" t.integer "winning_score" t.integer "losing_score" t.text "notes" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "venue_id" t.index ["venue_id"], name: "index_games_on_venue_id" end create_table "participants", force: :cascade do |t| t.integer "user_id" t.integer "game_id" t.string "result" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["game_id"], name: "index_participants_on_game_id" t.index ["user_id"], name: "index_participants_on_user_id" end create_table "users", force: :cascade do |t| t.string "name" t.string "email" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.string "password_digest" t.string "remember_digest" t.index ["email"], name: "index_users_on_email", unique: true end create_table "venues", force: :cascade do |t| t.string "name" t.datetime "created_at", null: false t.datetime "updated_at", null: false end CONTROLLER class GamesController < ApplicationController def show #game = Game.find(params[:id]) end def new #users = User.all #game = Game.new #game.participants.build end def create #game = Game.new(game_params) if #game.save redirect_to 'show' else render 'new' end end private def game_params params.require(:game).permit(:game_date, :winning_score, :losing_score, :notes, :venue_id, participants_attributes: [:user_id, :result, :_destroy]) end end FORM <%= simple_form_for #game do |f| %> <div id="winners"> <b>Winners</b> <% for i in 0..1 %> <%= f.simple_fields_for :participants do |p| %> <%= p.association :user, :collection => #users, label: false %> <%= p.input :result, :as => :hidden, :input_html => { :value => 'W' }%> <% end %> <% end %> </div> <%= f.input :winning_score, :collection => 15..30 %> <div id="losers"> <b>Losers</b> <% for i in 2..3 %> <%= f.simple_fields_for :participants do |p| %> <%= p.association :user, :collection => #users, label: false %> <%= p.input :result, :as => :hidden, :input_html => { :value => 'L' }%> <% end %> <% end %> </div> <%= f.input :losing_score, :collection => 0..30 %> <%= f.input :notes %> <%= f.submit "Submit!", class: "btn btn-primary" %> <% end %> RESPONSE Processing by GamesController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"p8081+wU7EqYV7PIIAOGP3N+Md4CJusFpL9qTm3CeC54fP7pTPEwtfYS5v5x+ErBWxGiB0oj1pklYGXwl/cRBw==", "game"=>{"participants_attributes"=>{"0"=>{"user_id"=>"3", "result"=>"W"}, "1"=>{"user_id"=>"2", "result"=>"W"}, "2"=>{"user_id"=>"1", "result"=>"W"}, "3"=>{"user_id"=>"6", "result"=>"W"}}, "winning_score"=>"18", "losing_score"=>"4", "notes"=>"13241234"}, "commit"=>"Submit!"} (0.1ms) begin transaction User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]] User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]] User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 6], ["LIMIT", 1]] (0.1ms) rollback transaction Rendering games/new.html.erb within layouts/application Rendered games/new.html.erb within layouts/application (69.4ms) Rendered layouts/_shim.html.erb (0.4ms) Rendered layouts/_header.html.erb (0.7ms) Rendered layouts/_footer.html.erb (0.3ms) Completed 200 OK in 199ms (Views: 144.9ms | ActiveRecord: 0.5ms)
#kkulikovskis comment worked for me. I changed: has_many :participants to has_many :participants, inverse_of: :game in the game model
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
Getting ActiveRecord::AssociationTypeMismatch in PostsController#create in Rails App
Started POST "/posts" for ::1 at 2016-01-16 20:55:15 -0800 Processing by PostsController#create as HTMLParameters: {"utf8"=>"✓", "authenticity_token"=>"RZREVs4Wy7ZWvo4u0xE5OmrawV2MYtxJNJZDfs+eQY8o2n1RthJsL5c1MklIpP+XlMGNbDYSD49fjna7Szq/1g==", "post"=>{"start"=>"2", "end"=>"1", "when(1i)"=>"2016", "when(2i)"=>"1", "when(3i)"=>"17", "when(4i)"=>"06", "when(5i)"=>"00"}} User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]] Completed 500 Internal Server Error in 5ms (ActiveRecord: 0.2ms) ActiveRecord::AssociationTypeMismatch (Location(#70172044981120) expected, got String(#70171989781540)):app/controllers/posts_controller.rb:8:in `create' Full Trace activerecord(4.2.4)lib/active_record/associations/association.rb:218:inraise_on_type_mismatch!' activerecord (4.2.4) lib/active_record/associations/belongs_to_association.rb:12:in 'replace' activerecord (4.2.4) lib/active_record/associations/singular_association.rb:17:inwriter' activerecord (4.2.4) lib/active_record/associations/builder/association.rb:123:in start=' activerecord (4.2.4) lib/active_record/attribute_assignment.rb:54:inpublic_send' activerecord (4.2.4) lib/active_record/attribute_assignment.rb:54:in _assign_attribute' activerecord (4.2.4) lib/active_record/attribute_assignment.rb:41:inblock in assign_attributes' actionpack (4.2.4) lib/action_controller/metal/strong_parameters.rb:185:in each_pair' actionpack (4.2.4) lib/action_controller/metal/strong_parameters.rb:185:ineach_pair' activerecord (4.2.4) lib/active_record/attribute_assignment.rb:35:in assign_attributes' activerecord (4.2.4) lib/active_record/core.rb:564:ininit_attributes' activerecord (4.2.4) lib/active_record/core.rb:281:in initialize' activerecord (4.2.4) lib/active_record/inheritance.rb:61:innew' activerecord (4.2.4) lib/active_record/inheritance.rb:61:in new' activerecord (4.2.4) lib/active_record/persistence.rb:33:increate' app/controllers/posts_controller.rb:8:in `create' post.rb class Post < ActiveRecord::Base belongs_to :user belongs_to :start, :class_name => 'Location' belongs_to :end, :class_name => 'Location' validates :start, presence: true validates :end, presence: true validates :when, presence: true validates :user_id, presence: true end PostsController.rb class PostsController < ApplicationController before_action :authenticate_user! def new #page_title = 'Add Post' #post = Post.new end def create #post = Post.create(post_params) # save the post if #post.save flash[:notice] = "Post Created" redirect_to posts_path else render 'new' end end ... private def post_params params.require(:post).permit(:start, :end, :when, :description, :seats, :round_trip).merge(user_id: current_user.id) end new.html.erb <h2>Add New Post</h2> <% if #post.errors.any? %> <% #post.errors.full_messages.each do |msg| %> <div class="alert alert-danger"><%= msg %> </div> <% end %> <% end %> <%= form_for #post do |f| %> <div class="form-group"> <%= f.select :start_location, Location.all.collect {|x [x.city_name, x.id]}, {:include_blank => 'Select One'} %> </div> <div class="form-group"> <%= f.select :end_location, Location.all.collect {|x| [x.city_name, x.id]}, {:include_blank => 'Select One'} %> </div> <div class="form-group"> <%= f.label :When %><br /> <%= f.datetime_select :when, :ampm => true, :minute_step => 15 %> </div> <button type="submit" class="btn btn-primary">Submit</button> <%=link_to "Cancel", root_path, class:'btn btn-default' %> <% end %> schema.rb ActiveRecord::Schema.define(version: 20160117041612) do create_table "locations", force: :cascade do |t| t.string "city_name" t.string "state_name" t.string "zip" t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "posts", force: :cascade do |t| t.integer "start" t.integer "end" t.datetime "when" t.text "description" t.integer "seats" t.integer "user_id" t.integer "round_trip" t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "users", force: :cascade do |t| t.string "first_name", default: "", null: false t.string "last_name", default: "", null: false t.integer "location_id" 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 I literally have no idea why I am getting this problem. A post has a start and end location. It also has a user_id, where the user has signed in through devise. Please help.
This isn't working because you're passing strings to attributes that accept a Location class instance. Since start and end are shown as being class Location in your model, your form either has nested attributes using fields_for, or you have selects to choose a location. If you have nested attributes you need to add accepts_nested_attributes_for :start, :end to your Post model and then update post_params to have the correct parameters def post_params params.require(:post).permit(:when, :description, :seats, :round_trip, start_attributes: [<fields in start>], end_attributes: [<fields in end>).merge(user_id: current_user.id) end if instead you have selects for choosing the locations, then you need to make sure they are returning start_id and end_id as the params and update your post_params to def post_params params.require(:post).permit(:start_id, :end_id, :when, :description, :seats, :round_trip).merge(user_id: current_user.id) end Update: Now that you've posted your form we can see you have selects. Your schema also shows that you have start and end in the posts model as integers. Normally those should be start_id and end_id or you will need to use the :foreign_key option with belongs to. Also, your two selects currently are passing parameters as start_location and end_location, which aren't valid parameters for any of your models. If you fix the naming of start_id/end_id then you would update the selects like <%= f.select :start_id, Location.all.collect {|x [x.city_name, x.id]}, {:include_blank => 'Select One'} %> and update your post_params to permit start_id and end_id. If instead you use the :foreign_key option, then it would be <%= f.select :start, Location.all.collect {|x [x.city_name, x.id]}, {:include_blank => 'Select One'} %>