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)
Related
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'
I want to get the username of comment author like this
comment.commenter
models/comment.rb
class Comment < ActiveRecord::Base
belongs_to :commenter
belongs_to :commentable, polymorphic: true
end
models/user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
validates :username, presence: true, uniqueness: true
has_many :comments, as: :commenter
end
When i try to create Comment directly to db using this line of code:
Comment.create(commentable_type: 'Pokemon', commentable_id: 1, content: 'great', commenter: 1)
It throws this error
NameError: uninitialized constant Comment::Commenter
from /var/lib/gems/2.3.0/gems/activerecord-4.2.6/lib/active_record/inheritance.rb:158:in `compute_type'
I've read somewhere as: is used only for polymorphic assocciations so that might be the case of my error but couldn't figure out how to get around this problem
I don't think as: is what you are looking for. I think your issue is similar to the issue in belongs_to with :class_name option fails
Try
# user.rb
has_many :comments, foreign_key: "commenter_id"
# comment.rb
belongs_to :commenter, class_name: "User", foreign_key: "commenter_id"
Let's explain a bit before going to the solution, if you write this code:
belongs_to :commentable, polymorphic: true
It implicitly means:
belongs_to :commentable, foreign_key: 'commentable_id', foreign_type: 'commentable_type', polymorphic: true
And
has_many :comments, as: :commentable
It specifies the syntax of polymorphic, that also means the foreign_key is commentable_id and foreign_type is commentable_type so if you want to change commentable to commenter, it is possible, you can do like this:
class Comment < ActiveRecord::Base
belongs_to :commenter, foreign_key: 'commentable_id', foreign_type: 'commentable_type', polymorphic: true
end
class User < ActiveRecord::Base
has_many :comments, as: commentable
end
That 's it!
For detail, please go through has_many and belongs_to documentation
What would be the best way to architect the model relationships and nested resources to build a game with: Users(from devise), Games, Players(join table w/ Games/Users). My problem is Users exist, but Players need to be created at the same time as games. Creating a game also has to create a player, which is possible but feels icky. Is there a better way to do this? I would like to avoid using transactions or filters to create new resources. Thanks.
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable
devise :omniauthable, :omniauth_providers => [:facebook, :twitter]
has_many :games
end
class Player < ActiveRecord::Base
validates :user_id, uniqueness: { scope: :game,
message: "can't join your own game" }
belongs_to :user
belongs_to :game
has_one :board
has_many :ships
end
class Game < ActiveRecord::Base
belongs_to :first_player, class_name: 'Player', foreign_key: 'first_player_id'
belongs_to :second_player, class_name: 'Player', foreign_key: 'second_player_id'
has_one :first_player_board, through: :first_player, source: :board
has_one :second_player_board, through: :second_player, source: :board
end
I ended up solving this by doing away with the player model all together and having Users have_many :games.
class Game < ActiveRecord::Base
belongs_to :first_player, class_name: 'User', foreign_key: 'first_player_id'
belongs_to :second_player, class_name: 'User', foreign_key: 'second_player_id'
has_one :first_player_board, through: :first_player, source: :board
has_one :second_player_board, through: :second_player, source: :board
end
In rails, I have this User model:
class User < ActiveRecord::Base
enum role: [:adult, :child, :admin]
after_initialize :set_default_role, :if => :new_record?
# belongs_to :spouse, :foreign_key => :spouse_id, :class_name => 'User', :inverse_of => :spouse
def set_default_role
self.role ||= :adult
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable
def marry(user)
self.spouse = user
user.spouse = self
end
end
I added spouses through this migration:
class AddFieldsToUser < ActiveRecord::Migration
def change
# for marriages
add_column :users, :spouse_id, :integer, index: true
end
end
and that works decently (though my inverse of function never worked # belongs_to :spouse, :foreign_key => :spouse_id, :class_name => 'User', :inverse_of => :spouse
). I am now trying to do another self join with a "child-parent" relationship. A parent can have many children and a child can have (many / two) parents. This is the migration I came up with:
class CreateParentalRelationships < ActiveRecord::Migration
def change
create_table :parental_relationships do |t|
t.references :parent, index: true
t.references :child
end
end
end
and I added this to the model:
has_many :children, :through => :parental_relationships, class_name: "User"
has_many :parents, :through => :parental_relationships, class_name: "User"
but the relationship did not work with the following error:
[7] pry(main)> u = User.find(3)
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 3]]
=> #<User id: 3, email: ...>
[8] pry(main)> u.children
ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association :parental_relationships in model Us
er
[9] pry(main)> u.parent
NoMethodError: undefined method `parent' for #<User:0x5e52eb0>
from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activemodel-4.1.8/lib/active_model/attribute_methods.rb:435:in
`method_missing'
[10] pry(main)> u.parents
ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association :parental_relationships in model Us
er
from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.1.8/lib/active_record/reflection.rb:690:in `che
ck_validity!'
[11] pry(main)> u2.children
ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association :parental_relationships in model Us
er
from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.1.8/lib/active_record/reflection.rb:690:in `che
ck_validity!'
What am I missing?
Setting up the parent child relationship takes some finagling.
class ParentalRelationship < ActiveRecord::Base
belongs_to :parent, class_name: 'User'
belongs_to :child, class_name: 'User'
end
class User < ActiveRecord::Base
has_many :parent_relationships,
foreign_key: 'child_id',
class_name: 'ParentalRelationship'
has_many :child_relationships,
foreign_key: 'parent_id',
class_name: 'ParentalRelationship'
has_many :parents,
through: :parent_relationships,
class_name: 'User'
has_many :children,
through: :child_relationships,
class_name: 'User'
has_and_belongs_to_many :marriages
belongs_to :current_marriage, class_name: 'Marriage'
def marry(spouse)
marriage = Marriage.create(users: [self, spouse])
marriage.users.each { |u| u.update(current_marriage: marriage ) }
marriage
end
def spouse
return nil unless current_marriage
current_marriage
.users.where.not('marriages_users.user_id' => id).first
end
def birth(child)
child.parents << self
child.parents << spouse if spouse
end
end
Note that we need to setup the relation to ParentalRelationship twice since we need to tell rails which foreign key it should look at for each type of relation (user is parent or child).
Since in these modern times people can actually have be married several times we need a Marriage model and a join table for users_marriages.
class Marriage < ActiveRecord::Base
has_and_belongs_to_many :users
validates :users, length: { minimum: 2, maximum: 2 }
end
rails g migration CreateUsersMarriagesJoinTable users marriages
Example app with specs: https://github.com/maxcal/sandbox/tree/31614819
I came up with a solution. Not sure if it is the best:
my new User model:
class User < ActiveRecord::Base
enum role: [:adult, :child, :admin]
after_initialize :set_default_role, :if => :new_record?
belongs_to :spouse, :foreign_key => :spouse_id, :class_name => 'User', :inverse_of => :spouse
has_many :parental_relationships
has_many :children, :through => :parental_relationships, class_name: 'User'
has_many :parents, :through => :parental_relationships, class_name: 'User'
def set_default_role
self.role ||= :adult
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable
def marry(user)
self.spouse = user
user.spouse = self
end
def birth(user)
self.children << user
user.parents << self
if self.spouse
self.spouse.children << user
user.parents << self.spouse
end
end
end
I had to edit a few migrations and models.
ParentalRelationships migration
class CreateParentalRelationships < ActiveRecord::Migration
def change
create_table :parental_relationships do |t|
t.references :user, index: true
t.references :child
t.references :parent
end
end
end
ParentalRelationship model:
class ParentalRelationship < ActiveRecord::Base
belongs_to :user
# , :class_name => "User"
# belongs_to :parent, :class_name => "User"
belongs_to :child, :class_name => "User"
belongs_to :parent, :class_name => "User"
end
So, to add relationships:
u = User.find(50)
u.birth(User.find(60))
I have these models:
class Item < ActiveRecord::Base
has_many :item_categoryships
has_many :categories, class_name: 'ItemCategoryship', foreign_key: 'category_id', :through => :item_categoryships
belongs_to :user
validates :title, presence: true
end
class Category < ActiveRecord::Base
has_many :item_categoryships
has_many :items, :through => :item_categoryships
belongs_to :user
validates :name, presence: true
end
class ItemCategoryship < ActiveRecord::Base
belongs_to :item
belongs_to :category
validates :item_id, presence: true
validates :category_id, presence: true
end
class User < ActiveRecord::Base
has_many :items
has_many :categories, class_name: 'Category'
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable, :async
end
But I found when I call item.categories will get a empty array !!! I have checked database, there is a record here.
When I test in the rails console, I didn't get any record back, just saw 'ActiveRecord::Associations::CollectionProxy []'.
What is this? I am using Rails 4.0.2.
Thanks you all.
ActiveRecord::Associations::CollectionProxy is ActiveRecord class for collection associations. Now, your code should work if you change line in Item class describing categories association to:
has_many :categories, through: :item_categoryships