How to handle foreign key in FactoryGirl - ruby-on-rails

I have a user model and a follower model, such that a user can have many followers. So in schema of follower model I have user_id column and a follower_by_user_id column. So in follower model a user can be followed by many followers. User id's are stored in user_id column and followers id's are whose id's are stored in as followed_by_user_id.
class User < ActiveRecord::Base
has_many :followed_users, :class_name => 'Follower', :foreign_key => 'user_id'
has_many :followers, :class_name => 'Follower', :foreign_key => 'followed_by_user_id'
validates :email, presence: true, format:{ with: /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i}
validates :name,presence:true
end
Above is user model
class Follower < ActiveRecord::Base
belongs_to :user
belongs_to :followed_by_user, :class_name => 'User', :foreign_key => 'followed_by_user_id'
validates :user, :followed_by_user, presence:true
validates_associated :user, :followed_by_user
end
above is follower model
FactoryGirl.define do
factory :user do
name {Faker::Name.name}
email {Faker::Internet.email}
end
factory :follower do
user
followed_by_user_id
end
followed_by_user_id is basically a user id only, or we can say user_id is foreign key for followed_by_user_id column. Im plain English followed_by_user_id is an id of an user who is following to some other user. So If any body can help how to include this foreign key relationship in follower factory for follower_by_user_id column?
Thanks in advance.

You can use association in your factory, like this (more info in the docs):
association :followed_by_user, factory: :user

You don't need so much complexity, use just:
followed_by_user factory: :user
This works like a charm.

Related

Rails - how to make association between these models (not based on "id", but on "email")

I have these models that obviously have more attributes, but for simplicity I kept them just like this:
class User < ActiveRecord::Base
has_many :subs, :foreign_key => :email, :class_name => "subs"
end
class Subscription < ActiveRecord::Base
belongs_to :plan
belongs_to :user
end
In the table subscriptions, there's a column called email. This column points to the table users where matches an email address of a single user (the column email is in both tables unique).
I would need to create an association between these two models based on the email value. But when I try to run this query (and to get all subscription for the currently sign in user):
<%= current_user.subs.inspect %>
I get this error message:
uninitialized constant User::subs
I'd like to ask you guys for helping me with this association.
Thanks
uninitialized constant User::subs
This code
class User < ActiveRecord::Base
has_many :subs, :foreign_key => :email, :class_name => "subs"
end
should be like this
class User < ActiveRecord::Base
has_many :subs, :foreign_key => :email, :class_name => "Subscription"
end
When you are using a class_name option with the associations,it should point to the respected model classname(in your case it is Subscription not subs).Since there is no model with the classname subs,it throws that exception.
class User < ActiveRecord::Base
has_many :subs, :foreign_key => :email, :class_name => "Subscription", :primary_key => :email
end
class Subscription < ActiveRecord::Base
belongs_to :plan
belongs_to :user, :foreign_key => :email, :class_name => "Subscription", :primary_key => :email
end
You have to set the correct Class name and also you have to set the primary key.

Rails model foreign key not working when specifying explicitly

I have a User model and a Message model. My message table has the columns created_for, and created_by and these are both foreign keys to the User table.
I'm currently getting this error message:
undefined methodcreated_for_id' for #`
How can I get this to work without having to change my columns to created_for_id and created_by_id?
class User < ActiveRecord::Base
has_one :message
end
class Message < ActiveRecord::Base
#belongs_to :user
belongs_to :created_by, :class_name => "User" # Basically tell rails that created_by is a FK to the users table
belongs_to :created_for, :class_name => "User" # Basically tell rails that created_for is a FK to the users table
attr_accessible :created_by, :created_for, :message
end
You can specify the foreign key for the belongs_to via:
belongs_to :created_for, class_name: 'User', foreign_key: :created_for
I suspect you are going to run into an issue having the relation name and foreign key attribute sharing a name. Here is the belongs_to documentation, scroll down to the "Options"

Rails: find records with has_one relationship

i have a user model that has many designs and also has_many design_request through designs
Now my design_request model has_one order. how can i get all the design requests with the order state == "paid" for a user
my user model is below
##User Model
has_many :designs
has_many :design_requests, through: :designs
##Design Model
has_many :design_requests
##Design Request Model
belongs_to :design
belongs_to :user
validates :business_name, :design_id, presence: true
delegate :name, to: :design
has_one :order, as: :item
have you tried something like:
user.design_requests.includes(:order).where(orders: {state: "paid"})
Does this work?
user.design_requests.select {|dr| dr.order.state == "paid"}

How do I validate uniqueness of join table with extra column in Ruby on Rails

I have a has many through relationship in a model that is self referencing. In the join table I also have an extra column that defines the source of the relationship. When adding a new object to that relationship I'd like to avoid duplicates in the join table based on the user_id, friend_id, and source_id
User Model
class User < ActiveRecord::Base
has_many :friendships
has_many :friends, :class_name => "User", :through => :friendships
end
Join Model
class Friendship < ActiveRecord::Base
attr_accessible :friend_id, :user_id, :source_id, :alert, :hide
# Relationships
belongs_to :user
belongs_to :friend, :class_name => "User"
has_one :source
end
I understand that I can do this
unless user.friends.include?(newFriend)
user.friendships.build(:friend_id => friendUser.id, :source_id => source.id)
end
But that seems like it will check to see if the new user exists in the current user's friends. I need to check on the join model level and make sure that the connection doesn't exist with the given source id.
I know there are several ways to accomplish this, but I'm pretty new to ruby on rails and am looking for the "rails way" to do it.
You can validate based on multiple columns in your intermediate table like this:
validates_uniqueness_of :user_id, :scope => [:friend_id, :source_id]

Rails model belongs to either one model or another

For a CRM app, I want to be able to associate a Person model directly to an Account model or to a Company model which in turn is associated to an Account model. Also, I want to associate an Address model to either a Company or a Person. This is what I have in mind:
class Account
has_many :Persons
has_many :Companies
end
class Person
belongs_to :Account
belongs_to :Company
has_one :Address
end
class Company
belongs_to :Account
has_many :Persons
has_one :Address
end
class Address
belongs_to :Person
belongs_to :Company
end
So an Account would be either a "person account" or a "business account" depending on the association. They would be mutually exclusive. I plan to have the foreign keys account_id and company_id in the Person table. By the same token I would have the foreign keys person_id and company_id in the Address table. One foreign key would be null in each case.
Is this okay in Rails? If not, any recommendations would be greatly appreciated.
Take a look at polymorphic associations. I think that's what you are looking for:
http://guides.rubyonrails.org/association_basics.html#polymorphic-associations
class Account
belongs_to :User, :polymorphic => true
end
class Person
belongs_to :Account, :as => :User
belongs_to :Company
has_one :Address, :as => :User
end
class Company
belongs_to :Account, :as => :User
belongs_to :Persons
has_one :Address, :as => :User
end
class Address
belongs_to :User, :polymorphic => true
end
...
Greetings Sven

Resources