Rails best way (or best practices) - ruby-on-rails

I have a model which I don't know how to focus the following issue:
I have been reading the following posts
before_create in rails model
before_create in user model -- set integer based on email (RAILS)
Access current_user in model
I have a project where I want to manage some properties (Assets).
I have Property, Owner, Company and Users.
The House and the Owner are linked in the DB with a FK so 1 Company has N Owners and 1 Company has N Properties.
The model User is linked to Company, so 1 Company has N users.
How can I access the company_id in the model Users in order to store this ID in the Properties and in the Owner model when the Property and Owner is created?
Do I have to do it in the controller and model?
Owner Class
class Owner < ApplicationRecord
acts_as_paranoid
has_many :property_owners
has_many :properties, :through => :property_owners
belongs_to :company
belongs_to :country
accepts_nested_attributes_for :properties
Property Class
class Property < ApplicationRecord
acts_as_paranoid
has_many :property_owners has_many :owners, :through =>
:property_owners
belongs_to :company belongs_to :country
This is the Company
Class Company < ApplicationRecord
has_many :properties
has_many :owners
And the last one is Users
class User < ApplicationRecord
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
before_create :set_default_role, only: :create
belongs_to :country
belongs_to :company
belongs_to :user_role
accepts_nested_attributes_for :company

Considering you have your associations right, in your controller, when a user creates, for example, a house entry:
def create
#property = current_user.company.properties.new(property_params)
....
end
Where current_user can be replaced by the variable containing the user currently logged on and property_params are the strong params, sent to the controller from your form.
Likewise for owner

Related

How to create a group of users (roomates) within one product (property) in Rails

I have a question on a platform I'm developing in Ruby on Rails 5.2.
I have an Owner model which is the owner of properties/property. The owner will post a property so that users (in this case roomates) can share the same property/house/department, etc.
I have Owners and I have Users (both tables are created using devise):
Owner.rb:
class Owner < ApplicationRecord
has_many :properties
end
User.rb:
class User < ApplicationRecord
#Theres nothing here (yet)
end
This is where the magic happens. Property.rb:
class Property < ApplicationRecord
belongs_to :owner
has_many :amenities
has_many :services
accepts_nested_attributes_for :amenities
accepts_nested_attributes_for :services
mount_uploaders :pictures, PropertypictureUploader
validates :amenities, :services, presence: true
scope :latest, -> { order created_at: :desc }
end
How can multiple users share a property? I'm aware that it will have a many-to-many association but I'm a bit confused how to connect these relationships so when the owner posts a property it will display something like:
Property available for: 3 users
And then begin to limit users until it completes the amount of users available.
This sounds like your average many to many assocation:
class User < ApplicationRecord
has_many :tenancies, foreign_key: :tenant_id
has_many :properties, through: :tenancies
end
class Tenancy < ApplicationRecord
belongs_to :tenant, class_name: 'User'
belongs_to :property
end
class Property < ApplicationRecord
has_many :tenancies
has_many :tenants, through: :tenancies
def availablity
# or whatever attribute you have that defines the maximum number
max_tenants - tenancies.count
end
end
You can restrict the number of tenants with a custom validation.
You can use a join table, called users_properties. This table will have a property_id and user_id. You'll then have the following in your properties model:
has_many :users_properties
has_many :users, through: :users_properties
Read more about it here https://guides.rubyonrails.org/association_basics.html

Is this the proper way to setup a has_many through association?

So I have 4 models..
A User model, a Question model an Answer model and a User_Question model.
Now I've created default seed questions that apply to all users i.e. #questions = Question.all
And these same questions every user can see, now how can I allow each user to write their own answer to these questions when they aren't directly associated with the question? I was given a solution to create a has_many through association, I just want to make sure I've set it up correctly please see code below, thanks:
user.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :user_questions
has_many :questions, through: :user_questions
end
answer.rb
class Answer < ActiveRecord::Base
attr_accessible :answer
has_many :user_questions
has_many :questions, through: :user_questions
end
question.rb
class Question < ActiveRecord::Base
attr_accessible :title, :body
belongs_to :user
has_one :answer
end
user_question.rb
class UserQuestion < ActiveRecord::Base
belongs_to :user
belongs_to :question
belongs_to :answer
end
If I understand this correctly you say your questions exist independently of users. Yet questions belongs to users.
My understand of this should be as follows:
User.rb
has_many :questions
has_many :answers
question.rb
belongs_to :user
has_many :answers
answer.rb
belongs_to :question
belongs_to :user
Notice the plurals as well for belongs_to and has_many.
The link for the guide is here but I don't think you need user_questions.
http://guides.rubyonrails.org/association_basics.html#the-has-many-association

How to use owner_id (instead of user_id) as foreign key?

I'm building an app where a user creates an arbitrary number of groups. When the group is created, the owner_id (in the group table) is set to that of the current_user.id.
I'm having some trouble showing the groups owned by a particular user though. Note that there is a many-to-many relationship between users and groups through the GroupMembers table.
Based on this question, I modified my group.rb model like such:
class Group < ActiveRecord::Base
has_many :group_members, :dependent => :destroy
has_many :users, :through => :group_members
belongs_to :owner, class_name: User, foreign_key: :owner_id
end
Adding just the last line to ("owner") to the model. The problem is that when I display the groups belonging to the user in my view:
<h3>User</h3>
<p>User: <%= #user.name %></p>
<p>Email: <%= #user.email if #user.email %></p>
<p>Groups:
<% #user.groups.each do |group|%>
<%= group.name %>
<% end %>
</p>
None of the groups show up. It seems that maybe I need to explicitly join to the groups table from inside the UsersController for this to work? But I'm not sure. I don't want to go too far down the rabbit hole here so I'm looking for some advice.
UPDATE:
Here is my User model:
class User < ActiveRecord::Base
has_many :group_members, :dependent => :destroy
has_many :groups, :through => :group_members
rolify
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :invitable, :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable
end
When you fetch #user.groups, you're using the :groups association on the User model, which is independent of the has_one :user association on the Group model. So the code you've provided above isn't the relevant bit. What you need is:
class User < ActiveRecord::Base
has_many :groups, foreign_key: :owner_id
end
Update: since you've already got a has_many :groups relation, you'll need to name this something else. e.g.,
class User < ActiveRecord::Base
has_many :owned_groups, foreign_key: :owner_id, class_name: Group
end
Then you'll need to update your view code to do #user.owned_groups instead of #user.groups, or you'll be fetching the wrong collection.
(p.s., the inverse relation on the Group model should be belongs_to :owner, class_name: User, foreign_key: :owner_id, not has_one. The difference is that a model that belongs_to another model is expected to hold the foreign key that defines the relationship, whereas a has_one relationship expects the foreign key to be on the associated table.)
You can do something like
# user.rb
has_many :owned_groups, foreign_key: 'owner_id', class_name: "Group"
That will distinguish between groups that the user owns vs groups that the user is in.

Many to Many, Through Relationship for Users

On Rails 4, I am using devise for my users and I have a scaffold for exercises.
Each user is to have many exercises, and each exercises have many users, this is done through a model called schedule.
I want to build a form, so that when a new exercise is created then it can be assigned to the Users. I am little lost on how to allow the schedule table to accept both the exercise_id and user_id when I create a new exercise. Any help is appreciated!
/user.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :schedules
has_many :exercises, :through => :schedules
/exercise.rb
class Exercise < ActiveRecord::Base
validates :description, presence: true
has_many :schedules
has_many :users, :through => :schedules
/schedules.rb
class Schedule < ActiveRecord::Base
belongs_to :exercise
belongs_to :user
Exercise Controller
def exercise_params
params.require(:exercise).permit(:description, :notes, :video, {:users=>[]})
end
edit
I am lost as what to do next in order to get the Schedule table to populate with Exercise_ids and User_ids.
Schema:
USERS
id
email
name
(standard columns from devise)
EXERCISES
id
description
created_at
updated_at
tag
notes
video_file_name
video_content_type
video_file_size
video_updated_at
SCHEDULE
id
exercise_id
user_id
position
created_at
updated_at

Recording the date an object is added to a has_many collection

Users on my site each have one list, which consists of a different type of users. I'm using a has_many through relationship to do this as follows:
List.rb:
class List < ActiveRecord::Base
belongs_to :company
has_many :list_applicants
has_many :applicants, through: :list_applicants
end
Applicant.rb:
class Applicant < ActiveRecord::Base
has_many :list_applicants
has_many :lists, through: :list_applicants
end
ListApplicant.rb
class ListApplicant < ActiveRecord::Base
attr_accessible :applicant_id, :list_id
belongs_to :applicant
belongs_to :list
end
Company.rb:
class Company < ActiveRecord::Base
has_one :list
end
When a user adds another user to their list, I'd like to record the date the user is added so they can sort their list of users by date added. What is the best way to do this?
You can use the created_at field of the ListApplicant model if it has one. If not, you may add manually a similar field.
UPDATE:
You can access the field by specifying both applicant and list like this:
#applicant.list_applicants.where(list_id: #list.id).first.created_at

Resources