My User has one Driver:
class User < ActiveRecord::Base
has_one :driver, :dependent => :destroy
end
class Driver < ActiveRecord::Base
belongs_to :user
end
User attributes include, user_first_name, user_last_name, user_email and user_phone number.
I want to be able to access these User attributes when working with the driver class.
For example:
#drivers = Driver.where( :user_first_name => "David )
Obviously the above code won't work, since user_first_name is not a Driver attribute, but is there a way to do this without looping through each user record?
I'm still new to Rails but hopefully this is helpful!
If you create a foreign key index to associate your model's tables within the database, then you should be able to access the data like so...
#user = User.find(params[:id])
#drivers = Driver.where( #user.user_first_name => "David" )
Also, not sure if it was a typo here, but you forgot to close the quotes with "David.
Related
I’m using Rails 4.2.7. Is there a way to automatically delete an orphaned entity when I no longer have an object pointing to it? I have these two models …
class MyObject < ActiveRecord::Base
belongs_to :address, :autosave => true, dependent: :destroy
class Address < ActiveRecord::Base
has_one :my_object
and in my PostGres “my_objects” table I have an “address_id” column that is a foreign key to the addresses table. Below is my method I use to save my “MyObject” entity with its accompanying address object …
def save_with_address(params)
transaction do
if !params[:address].nil?
# Address isn't an object yet, it is just a bunch of parameters
params[:address][:state] = params[:address][:state].nil? ? nil : State.find_by_id(params[:address][:state])
params[:address][:country] = params[:address][:country].nil? ? nil : Country.find_by_id(params[:address][:country])
address = Address.new(params[:address])
address.user = self
address.save
self.address = address
end
# Save the object
save
end
end
But I’m noticing that if the my_object entity had an address object before, that object remains in the database, despite the fact that it is orphaned. What is the easiest way to adjust things so that my orphaned address entity is removed from the database?
just update your model as below
class MyObject < ActiveRecord::Base
belongs_to :address, :autosave => true
class Address < ActiveRecord::Base
has_one :my_object, dependent: :destroy
I am trying to establish a direct relation via has_one between two models, Client and Address as in has_one :billing_address but Client doesn't have a direct relation to Address, Contact does, the models:
Client
class Client < ActiveRecord::Base
belongs_to :contact
accepts_nested_attributes_for :contact
end
Contact
class Contact < ActiveRecord::Base
has_one :client
has_many :addresses, dependent: :destroy
accepts_nested_attributes_for :addresses, allow_destroy: true
end
Address
class Address < ActiveRecord::Base
belongs_to :contact
enum kind: [:address, :shipping, :billing]
end
So what I want is to to be able to do Client.shipping_address or Client.billing_address, the enum in the Address model is what will allow the query. The reason behind that is because the Contact of Client will have two address records, one for billing and one for shipping and I want quick access via relations
I tried in the Client model:
has_one(:billing_address, -> { where(kind: :billing) }, class_name: Address, through: :contact)
But when in the view I o:
client.billing_address
I get a undefined method to_sym' for nil:NilClass And I can't seem to resolve it, thanks.
You need to specify the :source on the association since it cannot be inferred.
has_one :billing_address, through :contact, source: :addresses, -> { where(kind: :billing) }
Without :source, it's going to look for a :billing_address association on the Contact model.
Source
Update
After reading up on the enum docs, it looks like you may need to modify the scope, referencing the mapping directly:
-> { where(kind: Address.kinds[:billing]) }
I believe this is because the :kind field in the database is expected to be type INTEGER.
I have a user, user_profile and profile_type models. A user has_many user_profiles, a user_profile belongs_to a user and belongs_to a profile_type and a profile_type has_many user_profiles.
I have been reading on how to get this work but I am having problems figuring this out and any help would be much appreciated.
I know I could do this with SQL with a statement like this (freehand SQL, excuse mistakes), but I want to use ActiveRecord.
Select up.id, u.user_id, pt.connection_type
from user u
join user_profile up
on u.user_id = up.user_id
join profile_type pt
on pt.profile_type_id = up.profile_type_id
where u.username = "test"
I want to return nested user_profile objects for an associated user but I want the user_profile object to contain the profile_type.connection_type instead of the profile_type.profile_id.
Currently, if I do this,
user.user_profiles.all
add then iterate through the nested user_profiles that are returned, this is my output:
{
:id
:user_id
:profile_type_id
}
What I want is:
{
:id
:user_id
:profile_type.connection_type (instead of profile_type.profile_type_id)
}
User Model
class User < ActiveRecord::Base
has_many :user_profiles, autosave: true
has_many :account_settings, autosave: true
end
User_Profile Model
class UserProfile < ActiveRecord::Base
belongs_to :user
belongs_to :profile_type
end
User Profile Type Model
class ProfileType < ActiveRecord::Base
has_many :user_profiles
end
Try this:
user.account_settings.select("profile_type.*, profile_type.connection_type").all
I was able to figure out how to do this using Grape.
Since the association was already created, I can use Grape entities to expose what I needed out of the associations. It works seamlessly and I hope this helps anyone else who is having a similar problem.
To get what I was looking for, I needed to gather all user_profiles
userprofiles = user.user_profiles.all
Then, I presented this using Grape
present :user_profile_settings, userprofiles, with: API::V1::Entities::UserProfile
And, here is what my entities looked like:
class UserProfile < Grape::Entity
expose :profile_type, using: ProfileTypeEntity
end
class ProfileTypeEntity < Grape::Entity
expose :connection_type
end
I've read a bunch of questions but none of them are helping me with this problem. I am trying to create a form to make new forums but cannot get them to use the right category id.
<%= f.collection_select :category_id, Category.all, :id, :name %>
This creates a new forum but the id is not the category id from the drop down list. Here is the forums model
def new
#forum = Forum.new
end
def create
#forum = Forum.new(forum_params)
if #forum.save
redirect_to root_url
else
render 'new'
end
end
private
def forum_params
params.require(:forum).permit(:category_id, :name, :description )
end
end
Not quite sure what I am doing wrong here. Is it something to do with the foreign key? Any help would really be appreciated.
UPDATE
Forum Model
class Forum < ActiveRecord::Base
belongs_to :category
has_many :topics, dependent: :destroy
end
Category Model
class Category < ActiveRecord::Base
has_many :forums, dependent: :destroy
end
There is basically no category_id in the Forum model.
Here is a couple of things you can do to troubleshoot this. Run:
rails dbconsole
.schema
Check to see if you have category_id or not. If not, create a new migration for this.
Your initial code is correct. For some reason, I misread that your collection_select was already bound to the model.
right now I have a jobs table with
has_many :applicants
has_many:users, through: :applicants
and a applicant table with
belongs_to :job
belongs_to :user
and a user table with
has_many :applicants
has_many:jobs, through: :applicants
So Users are connected through applicant table to Jobs table and vise versa.
I'm not sure I'm updating the model correctly. Right now it looks like this:
def addapply
#job = Job.find(params[:id])
applicant = Applicant.find_or_initialize_by(job_id: #job.id)
applicant.update(user_id: current_user.id)
redirect_to #job
end
But I got to thinking - would not this replace whatever association was there before?
I started looking around and found this in someone else's code:
def update
unless params[:user_relationships][:user_category_ids]
# Set default user category if not selected.
#user.user_category_relationships.build(
:category_id => '1',
:created_by_user_id => #current_user.id,
:name_id => #name.id
)
else
params[:user_relationships][:user_category_ids].each { |user_category_id|
#user.user_category_relationships.build(
:category_id => user_category_id,
:created_by_user_id => #current_user.id,
:name_id => #name.id
)
}
end
end
I'm not sure how that all works but perhaps I do need to iterate through them with a .each before I update.
I don't want to replace what is already there, I just want to add to it.
In Short what is the best way to update (or rather add to) a has_many :through joined table association?
Why not?
def addapply
#job = Job.find(params[:id])
applicant = Applicant.where(job_id: #job.id, user_id: current_user.id).first_or_create
redirect_to #job
end