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'} %>

Resources