I recently updated my app from ruby 2.5.1 to 2.6.3 and from rails 5.0.7.2 to 5.2.3
I'm experiencing an issue with the update method of my user controller.
I got undefined method 'delete_if' for #<String:0x00007fac73d38c78> Did you mean? delete delete!
# PATCH/PUT /users/:id
def update
if #user.update(user_params)
redirect_to company_users_path(#user.company), notice: 'User was successfully updated.'
else
render :edit
end
end
EDIT this is my user model
class User < ApplicationRecord
paginates_per 10
extend Enumerize
has_many :user_challenges, dependent: :destroy
has_many :challenges, through: :user_challenges
has_many :user_events, dependent: :destroy
has_many :events, through: :user_events
has_and_belongs_to_many :objectives
has_one :binome_as_invited, class_name: 'Binome', foreign_key: 'invited_user_id', dependent: :destroy
has_one :binome_as_inviting, class_name: 'Binome', foreign_key: 'inviting_user_id', dependent: :destroy
belongs_to :company, optional: true
has_many :actions, dependent: :destroy
has_many :hello_messages, foreign_key: 'target_id'
has_many :custom_challenges, foreign_key: 'target_id'
has_many :sent_challenges, class_name: 'CustomChallenge', foreign_key: 'author_id'
has_many :received_challenges, class_name: "CustomChallenge", foreign_key: "target_id"
has_many :sent_challenges, class_name: "CustomChallenge", foreign_key: "author_id"
has_many :binome_invitations, foreign_key: "invited_user_id"
has_many :device_tokens
delegate :challenges, to: :company, prefix: true
acts_as_paranoid
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
include DeviseTokenAuth::Concerns::User
attr_accessor :secret_code
validate :company_code, on: :create
validates :first_name, :last_name, :phone, :age, :ki_count, presence: true
ROLES = ['admin', 'company_admin', 'user', 'inactive']
enumerize :role, in: ROLES
scope :with_avatar, -> { where.not(avatar: 0) }
could it be acts_as_paranoid gem? Or maybe a gem I need to update? It's definitely since I update rails or ruby or maybe a single gem.
EDIT2 the last item of the stacktrace seems to be linked to the gem devise_token_auth
devise_token_auth (1.1.0) app/models/devise_token_auth/concerns/user.rb:218:in `destroy_expired_tokens'
Related
im getting error when im tring to save my object of type Wedding. I have many foreign keys to the same class and on create action i gets NameError (uninitialized constant Wedding::user)
Wedding.rb
class Wedding < ApplicationRecord
belongs_to :creator, class_name: 'user', foreign_key: 'creator_id'
belongs_to :second_creator, class_name: 'user', foreign_key: 'second_creator_id', optional: true
belongs_to :third_creator, class_name: 'user', foreign_key: 'third_creator_id', optional: true
belongs_to :bride, class_name: 'user', foreign_key: 'bride_id'
belongs_to :groom, class_name: 'user', foreign_key: 'groom_id'
belongs_to :photo_type, class_name: 'tier', foreign_key: 'photo_type', optional: true
belongs_to :video_type, class_name: 'tier', foreign_key: 'video_type', optional: true
enum wedding_status: { reservation: 0, signed: 1, post: 2, delivered: 3, done: 4 }
end
User.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
before_save :set_full_name
has_many :weddings, class_name: 'wedding', foreign_key: 'creator_id'
has_many :weddings, class_name: 'wedding', foreign_key: 'second_creator_id'
has_many :weddings, class_name: 'wedding', foreign_key: 'third_creator_id'
has_many :weddings, class_name: 'wedding', foreign_key: 'bride_id'
has_many :weddings, class_name: 'wedding', foreign_key: 'groom_id'
validates :role, :email, :first_name, :last_name, presence: true
enum role: { super_admin: 0, admin: 1, bride: 2, groom: 3 }
protected
def set_full_name
self.full_name = "#{first_name} #{last_name}"
end
end
wedding_controller.rb
def create
#wedding = Wedding.new(wedding_params)
if #wedding.save
redirect_to weddings_path, notice: t('views.weddings.create.notice')
else
render :new
end
end
private
def wedding_params
ret = params.require(:wedding).permit(:creator_id, :bride_id, :groom_id, :photo_type_id,
:video_type_id, :wedding_date, :wedding_location, :reception_location, :bride_house,
:groom_house, :is_session_photo, :is_session_video, :session_location, :session_date,
:price, :is_paid, :advance, :is_advance_paid, :is_photo, :is_video, :video_link,
:photo_link, :thumb_image, :second_creator_id, :third_creator_id, :wedding_status)
ret
end
Im using simple_form to render my form.
The class name should be capitalized.
belongs_to :creator, class_name: 'User', foreign_key: 'creator_id'
You need to change all other lines (the same issue)
I am working on a Rails app with Sqlite and have a users table associated with several other tables. When trying to rename a column in Users, I'm getting the subject error when running rails db:migrate.
I see a lot of posts here with similar issues, but none has worked. Specifically, the common remedy seems to be to use "dependent: :destroy" on all has_many and has_one associations. I am doing this but am still getting the error.
What am I doing wrong?
Below is my code:
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_one :profile, dependent: :destroy
has_many :bikes, dependent: :destroy
has_many :bookings, dependent: :destroy
has_many :rented_bikes, through: :bookings, source: :bike
has_many :conversations, dependent: :destroy
has_many :likes, dependent: :destroy
has_many :liked_bikes, through: :likes, :source => :bike
has_many :viewed_bikes, through: :views, :source => :bike
has_many :views, dependent: :destroy
has_many :reviews, dependent: :destroy
end
class Profile < ApplicationRecord
belongs_to :user
end
class Bike < ApplicationRecord
belongs_to :user
has_many :images, dependent: :destroy
has_many :bookings, dependent: :destroy
has_many :booked_users, through: :bookings, source: :user
has_many :conversations, dependent: :destroy
has_many :likes, dependent: :destroy
has_many :liking_users, :through => :likes, :source => :user
has_one :amenity, dependent: :destroy
has_many :places, dependent: :destroy
has_many :views, dependent: :destroy
end
class Booking < ApplicationRecord
belongs_to :bike
belongs_to :user
has_one :review, dependent: :destroy
validates :date_start, presence: true
validates :date_end, presence: true
validates :user_id, presence: true
end
class Conversation < ApplicationRecord
belongs_to :user
belongs_to :bike
has_many :messages, dependent: :destroy
end
class Like < ApplicationRecord
belongs_to :user
belongs_to :flat
end
class View < ApplicationRecord
belongs_to :user
belongs_to :flat
end
class Review < ApplicationRecord
belongs_to :user
belongs_to :booking
end
Migration:
class ChangeCustomerIdToUserId < ActiveRecord::Migration[5.1]
def change
rename_column :users, :customer_id, :client_id
end
end
You have a couple problems happening at once:
SQLite doesn't support renaming columns so the ActiveRecord driver implements column renaming the hard way: create a new table with the new column names, copy all the data, drop the original table, rename the new one. Note that this has recently changed so the latest SQLite does support renaming columns in-place.
You have foreign keys in other tables that reference your users table.
(2) is what is triggering your error during your migration: you can't drop a table (see (1)) when there are foreign keys referencing it since dropping the table would violate those foreign keys.
The solution is to drop all the offending FKs in your migration, then do the rename_column, and then add all the FKs back again. Another option would be to try to turn off FKs and turn them back on in your migration, something like:
connection.execute("PRAGMA defer_foreign_keys = ON")
connection.execute("PRAGMA foreign_keys = OFF")
rename_column :users, :customer_id, :client_id
connection.execute("PRAGMA foreign_keys = ON")
connection.execute("PRAGMA defer_foreign_keys = OFF")
might work.
There was a commit made to Rails three months ago that should fix this problem but I don't think it has made it into any release version yet.
I have an issue with my rails project. There is a user that is not being returned when trying to fetch the record using find(:id) while the record is being fetched when using User.find_by(:email)
Here is an example:
User.find(333)
ActiveRecord::RecordNotFound: Couldn't find User with 'id'= 333
```User.find_by(email: "example#me.com")
=> #<User id: 333, email: "example#me.com", created_at: "2017-10-06 01:30:13", updated_at: "2018-01-03 22:54:31, ..."
```
BTW, I am using postgresql, and the project is hosted on aptible.
Thanks in advance.
Update
It is really strange. I was able to update another user's id to 333 without getting a conflict error. However I am not able to update any field in the original user with id = 333
Replies to comments:
User.find(333)
D, [2018-01-09T01:14:22.070276 #127] DEBUG -- : User Load (1.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 333]]
ActiveRecord::RecordNotFound: Couldn't find User with 'id'=333```
User.find_by(email: "example#me.com")
D, [2018-01-09T01:38:32.350705 #127] DEBUG -- : User Load (1.5ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'example#me.com' LIMIT 1
=> #<User id: 333, email: "example#me.com", created_at: "2017-10-06 01:30:13", updated_at: "2018-01-03 22:54:31",```
User.find_by_id(333)
D, [2018-01-09T01:53:31.652219 #127] DEBUG -- : User Load (1.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = 333 LIMIT 1
=> nil
User.where(id: [333])
D, [2018-01-09T18:14:15.389575 #129] DEBUG -- : User Load (1.3ms) SELECT "users".* FROM "users" WHERE "users"."id" IN (333)
=> #<ActiveRecord::Relation []>
User Model:
(I omitted the methods in the model since they don't affect the behavior of fetching a record)
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, #:registerable,
:recoverable, :rememberable, :trackable, :validatable, :timeoutable
# has_many :posts, dependent: :destroy
has_many :cards, dependent: :destroy
has_many :card_templates, dependent: :destroy
has_many :provider_posts, class_name: "Post", foreign_key: "provider_id"
has_many :foods, dependent: :destroy
has_many :comments, dependent: :destroy
has_many :messages, foreign_key: :sender_id, dependent: :destroy
has_many :received_messages, class_name: "Message", foreign_key: "chatroom_id"
has_many :notifications, dependent: :destroy
has_many :conversations, dependent: :destroy
has_many :chatrooms, through: :conversations
has_many :chat_messages, dependent: :destroy
has_many :chatusers
has_many :chats, through: :chatusers
# has_many :partnerships
has_many :providers, class_name: "Partnership", foreign_key: "user_id", dependent: :destroy
has_many :patients, class_name: "Partnership", foreign_key: "provider_id", dependent: :destroy
has_many :provider_users, through: :providers, source: :provider
has_many :patient_users, through: :patients, source: :patient
# has_many :schedulings
has_many :provider_schedulings, class_name: "Scheduling", foreign_key: "user_id", dependent: :destroy
has_many :patient_schedulings, class_name: "Scheduling", foreign_key: "provider_id", dependent: :destroy
has_many :scheduled_providers, through: :provider_schedulings, source: :provider
has_many :scheduled_patients, through: :patient_schedulings, source: :patient
has_many :mobile_devices, dependent: :destroy
has_many :hidden_messages, dependent: :destroy
has_many :star_categories, dependent: :destroy
has_many :starred_cards, through: :star_categories
has_many :user_programs, dependent: :destroy
belongs_to :profile_status
belongs_to :appointment_frequency
has_many :glucoses, dependent: :destroy
has_many :healthkits, dependent: :destroy
has_many :scales, dependent: :destroy
has_many :progress_images, dependent: :destroy
has_many :temp_food_images, dependent: :destroy
# accepts_nested_attributes_for :provider_users
# accepts_nested_attributes_for :providers
mount_uploader :avatar, AvatarUploader
mount_base64_uploader :avatar, AvatarUploader
mount_uploader :license, LicenseUploader
mount_base64_uploader :license, LicenseUploader
mount_uploader :insurance, InsuranceUploader
mount_base64_uploader :insurance, InsuranceUploader
mount_uploader :insurance2, InsuranceUploader2
mount_base64_uploader :insurance2, InsuranceUploader2
validates :email, presence: true, uniqueness: true
validates :phone, presence: true, uniqueness: true
validates :first_name, presence: true
validates :last_name, presence: true
before_create :set_default_timezone
before_create :clear_phone
before_create :create_auth_token
after_commit :sync_to_drchrono_and_salesforce, on: :create
after_commit :create_chatroom, on: :create
after_commit :create_default_cards, on: :create
after_commit :check_pending_appointments, on: :create
after_commit :connect_tech_provider, on: :create
after_update :check_pending_appointments, if: :email_changed?
after_update :start_drchrono_refresh_token_worker, if: :drchrono_access_token_changed?
after_update :start_fitbit_refresh_token_worker, if: :fitbit_access_token_changed?
after_update :sync_stats_to_salesforce
after_update :regenerate_progress_images, if: :last_seen_at_changed?
scope :patients, -> { where("provider != true and demo != true") }
scope :providers, -> { where(provider: true) }
scope :is_app, -> { where(app: true) }
end
Not sure why the following worked.
In the psql console I updated the email of user 333 and then it started to work. I was able to select it. I was also able to update the email to it's original value.
Maybe it is an issue with aptible db.
In ActiveAdmin, when I want to delete a user I have the following error :
ActiveRecord::InvalidForeignKey in Admin::UsersController#destroy
PG::ForeignKeyViolation: ERROR: update or delete on table "users" violates foreign key constraint "fk_rails_b080fb4855" on table "notifications" DETAIL: Key (id)=(15) is still referenced from table "notifications". : DELETE FROM "users" WHERE "users"."id" = $1
I already have has_many :notifications, dependent: :destroy in my User model so I don't understand the error.
Notification model:
class Notification < ActiveRecord::Base
before_validation :check_modeles
validates :message, presence: true
validates :modele, presence: true
validates :user_id, presence: true
validates :contact_id, presence: true
validates_associated :user
belongs_to :user
belongs_to :contact, :class_name => "User", :foreign_key => "contact_id"
User model :
class User < ActiveRecord::Base
before_validation :check_genres
before_validation :set_image
before_validation :init_attrs
before_create :set_name
before_create :create_mangopay
after_create :set_centres_interets
after_create :set_preferences_musicales
after_create :check_on_create
after_update :check_on_update
before_update :create_mangopay_bank_account
before_destroy :remove_contact_notifications
acts_as_mappable :default_units => :kms,
:lat_column_name => :last_lat,
:lng_column_name => :last_lng
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
has_one :fil, dependent: :destroy
has_one :preferences_voyage, dependent: :destroy
has_one :verification, dependent: :destroy
has_many :badges, dependent: :destroy
has_many :favoris , dependent: :destroy
has_many :centres_interets, dependent: :destroy
has_many :preferences_musicales, dependent: :destroy
has_many :recommandations, dependent: :destroy
has_many :reputations, dependent: :destroy
has_many :reservations, dependent: :destroy
has_many :routes, dependent: :destroy
has_many :trajets_reguliers, dependent: :destroy
has_many :vehicules, dependent: :destroy
has_many :contact_notifications, foreign_key: 'contact_id', class_name: 'Notification', dependent: :destroy
has_many :notifications, dependent: :destroy
has_many :recherches, dependent: :destroy
has_many :blocages, dependent: :destroy
has_many :messageries, dependent: :destroy
has_many :messages, dependent: :destroy
validates :date_naissance, presence: true
validates :first_name, presence: true
validates :last_name, presence: true
Maybe the has_many :notifications, dependent: :destroy only affect the user and not the contact? If so, how do i fix it?
Ok, maybe your best bet is to just remove the foreign key constraints.
Create a migration with the following lines
remove_foreign_key :notifications, :users
remove_foreign_key :notifications, column: :contact_id
Rails doesn't require the foreign key constraints, and they're clearly not helping here.
You can also remove it by name...
remove_foreign_key :notifications, name: :fk_rails_b080fb4855
In your PostgreSQL database table notifications you have two different foreign keys that relate to users the user_id and the contact_id and the dependent: destroy only relates to the user_id.
Add another has_many to your User model to cover the second association
has_many :contact_notifications, foreign_key: 'contact_id', class_name: 'Notification', dependent: :destroy
Also, ensure that you're using the destroy method when you're deleting a user
#user.delete # will NOT run callbacks
#user.destroy # will run callbacks including destroying dependent records
To be sure that the issue is related to contact_id you can try removing those records with a manual process
class User
before_destroy :remove_contact_notifications
def remove_contact_notifications
Notification.where(contact_id: id).destroy_all
Notification.where(user_id: id).destroy_all
end
end
I've been following Michael Heartl tutorial to create a follow system but I have a strange error: "undefined method `find_by' for []:ActiveRecord::Relation". I'm using devise for authentication.
My view /users/show.html.erb looks like that:
.
.
.
<% if current_user.following?(#user) %>
<%= render 'unfollow' %>
<% else %>
<%= render 'follow' %>
<% end %>
User model 'models/user.rb' :
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
has_many :authentications
has_many :relationships, foreign_key: "follower_id", dependent: :destroy
has_many :followed_users, through: :relationships, source: :followed
has_many :reverse_relationships, foreign_key: "followed_id", class_name: "Relationship", dependent: :destroy
has_many :followers, through: :reverse_relationships, source: :follower
def following?(other_user)
relationships.find_by(followed_id: other_user.id)
end
def follow!(other_user)
relationships.create!(followed_id: other_user.id)
end
def unfollow!(other_user)
relationships.find_by(followed_id: other_user.id).destroy
end
end
Relationship model 'models/relationship.rb':
class Relationship < ActiveRecord::Base
attr_accessible :followed_id, :follower_id
belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"
validates :follower_id, presence: true
validates :followed_id, presence: true
end
Rails is telling me that the issue is in user model : "relationships.find_by(followed_id: other_user.id)" because mthod is not defined, but I don't understand why ?
I believe find_by was introduced in rails 4. If you are not using rails 4, replace find_by by a combination of where and first.
relationships.where(followed_id: other_user.id).first
You can also use the dynamic find_by_attribute
relationships.find_by_followed_id(other_user.id)
ASIDE:
I suggest you change your following? method to return a truthy value rather than a record (or nil when no record is found). You can do this by using exists?.
relationships.where(followed_id: other_user.id).exists?
One big advantage of this is it doesn't create any object and just returns a boolean value.
You can use
relationships.find_by_followed_id( other_user_id )
or
relationships.find_all_by_followed_id( other_user_id ).first