Why can't I call create on this has_one relationship? - ruby-on-rails

I'm missing something basic. This is Rails 3.2.16.
In my app:
User has_one Subscription
Subscription belongs_to User
Subscription belongs_to Plan
But when I try to do this:
user.subscription.create(plan_id: plan.id)
I get the following:
NoMethodError: private method `create' called for #<Subscription:0x007f80f1f4dfc0>
Yet this works fine:
Subscription.create(user_id: user.id, plan_id: plan.id)

Perhaps you're looking for this method:
user.create_subscription(plan_id: plan.id)
From the RoR guide:
When initializing a new has_one or belongs_to association you must use the build_ prefix to build the association, rather than the association.build method that would be used for has_many or has_and_belongs_to_many associations. To create one, use the create_ prefix.

In your models you should have the associations like this:
class Subscription < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_one :subscription
end
Read here

one way to do that
user.subscription = Subscription.create(plan_id: plan.id)

Related

Why can't I create an ActiveRecord entry like this?

I have two associated models:
Class User < ApplicationRecord
has_many :company_accounts
end
Class CompanyAccount < ApplicationRecord
belongs_to :users
end
I want to create a CompanyAccount for an existing user. This works:
#user.company_accounts.create
Why doesn't this work?
CompanyAccount.create(user_id: #user.id)
The full error message is "Users must exist". I'm using rails 5.0.1.
Try with belongs_to :user, it has only one user not many.

creating an association and scoping

I read "Multitenancy with Rails" by Ryan Bigg and I'm creating a multi-tenant application using Ruby on Rails.
I make two models, Tenant and User.
Tenant has many User, User belongs to Tenant.
To associate these models, I made this file,
active_record_extensions.rb
ActiveRecord::Base.class_eval do
def self.scoped_to_tenant
belongs_to :tenant
association_name = self.to_s.downcase.pluralize
Tenant.has_many association_name.to_sym, class_name: self.to_s
end
end
and add "scoped_to_tenant" to User.rb
class User < ActiveRecord::Base
scoped_to_tenant
end
When I want to get all users of one Tenant(id=1), I can get it by these code.
Tenant.find(1).users
The question is, what is the difference between I write
belongs_to :tenant
to User.rb and use scoped_to_tenant method ?
In both case, Tenant.rb is this.
Tenant.rb < ActiveRecord::Base
has_many :users
end
Thank you for answer.
I may get English wrong, so please tell me if you can't understand something.
A call to scoped_to_tenant method call the method belongs_to for you and add the many association to Tenant.
This is same as doing this :
# app/model/user.rb
class User < ActiveRecord::Base
belongs_to :tenant
end
# app/model/tenant.rb
class Tenant < ActiveRecord::Base
has_many :users
end
The benefit of the scoped_to_tenant is that you don't care about adding has_many relationship to Tenant model.
If you only have one model to associate with Tenant, you don't need this extension.

Rails :has_many of a :has_one through

I am having issues setting up model relations in Rails.
I have a User. A user can have many requests. A request can have one response. I set up my models like this:
Class User < ActiveRecord::Base
has_many :user_requests
has_many :request_responses, through: :user_requests
end
Class UserRequest < ActiveRecord::Base
belongs_to :user
has_one :request_response
end
Class RequestResponse < ActiveRecord::Base
belongs_to :user_request
end
Whenever I try to do something like:
UserRequest.request_response.id
I get errors that say either the relationship doesn't exist or the column does not exist in the table. Have I set up my relationships incorrectly?
You will get error:
UserRequest.request_response.id
Because:
request_response is expected to be a class method of UserRequest.
Association is defined as request_responses, not request_response, so calling user. request_response won't work either.
What to do?
call user.request_response_ids where user = User.first.

Polymorphic association fails

In my rails 3.2 application I have a User model and a Physician model with the following polymorphic associations:
User
class User < ActiveRecord::Base
attr_accessible :authenticatable_id, :authenticatable_type, :email
belongs_to :authenticatable, polymorphic: true
end
Physician
class Physician < ActiveRecord::Base
attr_accessible :name
has_one :user, as: :authenticatable
end
I wanted to test these out in the console and encountered a strange thing. Doing:
p = Physician.new
p.user.build
gives me NoMethodError: undefined method 'build' for nil:NilClass - but why would the physician's user attribute be nil?
Strangely, when I change the physician model to has_many :users instead of has_one :user and do
p = Physician.new
p.users.build
everything works fine.
What am I missing to get the has_one association to work?
You probably should do p.build_user since has_one doesn't add association.build method. You can also check apidock about methods has_one and has_many 'injects' into your model.
It is not entirely clear to me, but it seems that your are creating a Physician that is also a User. So it is able to make use of the features a User provides.
Your implementation creates two objects one Physician and oneUser, but when strictly looking at the situation, both are the same Physician/User.
So you should let Physician inherit from User:
class Physician < User
and remove the polymorphic relation between Physician and User.

.build method not creating association in the join table

I have three Models setup with the following associations
class User < ActiveRecord::Base
has_many :faculties
has_many :schools, :through => :faculties
end
class School < ActiveRecord::Base
has_many :faculties
has_many :users, :through => :faculties
end
class Faculty < ActiveRecord::Base
belongs_to :user
belongs_to :school
end
and in my controller i go to create a school and assign the user
class SchoolsController < ApplicationController
def create
#school = current_user.schools.build(params[:school])
...
end
end
When I login and submit the form the flash displays success, but the association doesn't build on the join table.
I tried it inside the apps console and it builds the association just fine.
I've been stuck on this for a couple days now and I just cannot figure out what I am missing. Thank in advance for any and all advice
The build method does not save the object. You need to explicitly call #school.save.
Two things: If the schools association is :through a has_many association, you will have to select which parent the School exists through.
So, for instance, if you were to nest School resources under users as in /users/:id/faculties/:id you could create a school via current_user.faculties.find(params[:faculty_id]).schools.build(params[:school]).save
Based on the example code, it looks like the fundamental problem is that the has_many xxx, :through syntax is being used without specifying the id of the faculties record. Remember two things: 1) ActiveRecord doesn't natively support composite primary keys, and 2) you must call #save on associated records created using #build. If you remember these, you should be fine.

Resources