Passing params when using after_create method Rails - ruby-on-rails

I have an application where a user adds a subscription and an account is automatically created for that subscription. I also want to pass the current user to the account model as the account_manager. So far I have:
class Subscription < ActiveRecord::Base
has_one :account
after_create :create_account #after a subscription is created, automatically create an associated account
def create_account
Account.create :account_manager_id => "1" #need to modify this to get current user
end
end
class Account < ActiveRecord::Base
has_many :users
belongs_to :account_manager, :class_name => 'User', :foreign_key => 'account_manager_id'
belongs_to :subscription, :dependent => :destroy
end
This works fine for the first user obviously but any attempts I've made to pass current_user, self, params, etc fails. Also when I use the def method the subscription ID is no longer passed to the account. I tried passing the current user through the AccountController but nothing happens. In fact I can still create an account if my AccountController is completely blank. Is after_create the best way to create an associated account and how do I pass the user to the account model? Thanks!

If you are using devise, you can do this directly in the controller with the current_user helper without a callback:
# subscriptions_controller.rb
def create
...
if #subscription.save
#subscription.create_account(account_manager: current_user)
end
end

Related

Rails: How to create a user that has a `belongs_to` association

I am brand new to the world of rails so please forgive my ignorance with this question :)
I am currently setting up a new app that has two models:
Account
User
My seed file looks like this:
account = Account.create!(name: 'Account Name')
account.users.create!(
first_name: 'Test',
last_name: 'Test',
email: 'test#test.com,
password: 'test',
owner: true
)
And the users model is:
class User < ApplicationRecord
belongs_to :account
...
end
I have created a custom Devise registrations controller to let new users sign up:
class Users::RegistrationsController < Devise::RegistrationsController
# GET /sign_up
def new
render inertia: 'Auth/Register', props: {}
end
# POST
def create # rubocop:disable Lint/UselessMethodDefinition
super
end
def sign_up_params
params.require(:user).permit( :email, :password, :first_name, :last_name)
end
end
BUT! I need to pre-create an account for a user before I actually create the user here and this is something I have been stuck on for a few days with no luck (to the point I've considered changing the association's).
The error is:
Account must exist
Which makes sense because we don't have an account when we create a new user which is what i need to do before the user is registered.
My best guess was I needed to do something like:
# POST
def create
account = Account.create!(name: 'Test')
account.users.create!(sign_up_params)
end
to mimic the logic of the seeds file but this seems distinctly wrong to me and doesn't work.
So my question is, is it possible and how can I pre-create an Account model for a user and then associate it to the user in the registrations create method before the user is persisted to the database?
In my final production code, the goal would be to create an Account type that will be created and associated with a user on registration but for now just getting a very basic MVC up and running is the goal :)
Thank you so much in advance for any help!
First off, I think the account is supposed to belong to the user, not the opposite.
The user model User.rb should look like this:
has_one :account
And the account model Account.rb should look like this:
belongs_to :user
And to create an account once the user is created, you can simply add this line to your user model:
after_create :create_account
and the account will be created automatically.
What about using?
user = User.new(sign_up_params)
user.build_account(name: 'Test')
user.save!
The problem is the line belongs_to :account in User model.
I would suggest you break your User model in two models
User
UserDetails
You can then add belongs_to :account in UserDetails model.
This will help in independent creation of users, will not be affected by account.
Something like below.
class User < ApplicationRecord
has_one :user_detail
...
end
class UserDetails < ApplicationRecord
belongs_to :user
belongs_to :account
...
end
class Account < ApplicationRecord
has_many :user_details
...
end

Rails 4 + Devise: After create user, create XYZ

I have a User model that gets created through Devise, and after it's creation, I would like to automatically create a new Client (another model in my app). The new Client's atrribute, :user_id, should be equal to the :id of the User that was just created. I believe I need to use something like:
class Users::RegistrationsController < Devise::RegistrationsController
after_create :create_client
def create_client
Client.create(:user_id, :id) # Not sure what should go here
end
end
Is this the correct way to accomplish this? Also, if associations are important Client belongs_to :user and User has_one :client
You can add an after_create callback in User model(user.rb), check here for more information on how to create has_one associations.
class User < ActiveRecord::Base
after_save :add_client
def add_client
self.create_client(client_attribute1: value, client_attribute2: value)
end
end

Limit create action to 1 post per user

I want to make user to have only one matriculation per user. However I get error "undefined method `matriculations' for nil:NilClass". How could I make it work? (I use devise as user auth if its matter).
def matriculation_limit
if self.user.matriculations(:reload).count <= 1
errors.add(:base, "Yuo already have one matriculation form")
else
redirect_to new_matriculation_path
end
end
With a has_one association, then the association finder method is singular like #user.matriculation, not #user.matriculations. And there's no point counting them because there will only be one.
Regarding comment:
You don't need to check anywhere how many matriculations the user has, because it's a singular association, so you'll just be updating the association (changing the ID in the foreign key column matriculation_id in the users table)
class User < ActiveRecord::Base
has_one :matriculation, :class_name => "User", :foreign_key => "matriculation_id"
end
class Matriculation < ActiveRecord::Base
belongs_to :user
end
# some controller action...
#user.matriculation = Matriculation.find(params[:matriculation_id]) # or something!
self.user == user_object.user. And seems like you dont have method user for class user. ANd another things, you have has_one, so you have to use self.matriculation
so correct would be
if self.matriculation
errors.add(:base, "Yuo already have one matriculation form")
else
redirect_to new_matriculation_path
end

Rails 3 and Devise: How to register an account and user in the registration page?

I need a registration page to record a new account that has user as a nested attribute. For example:
MODELS
class User < ActiveRecord::Base
belongs_to :account
validates :account_id, :presence => true
...
class Account < ActiveRecord::Base
has_many :users, :dependent => :destroy
accepts_nested_attributes_for :users
...
TABLES
accounts
id: 5
users
id: 32
email: someuser#gmail.com
account_id: 5
I know to override the registrations controller I have to do something like this...
class RegistrationsController < Devise::RegistrationsController
def new
super
end
def create
super
end
end
I have the Devise default registration page. But how can I register an account and a user that belongs to that account?
As it seems that your Devise resource is user, maybe you want to use nested attributes on users, instead of account.
Then, you will be able to do the registration using nested attributes and then assign an account with it.

How do I set ActiveRecord model attribute when using .build method with Rails 3.2 (many-to-many)

I'm working on a sort of project management app with Rails (my Rails skills is kinda rusty). I have two model objects, in this case User and Account, which have a many-to-many relationship (Company could maybe be a better name for Account). When a user signs up a new Account is created (with .build) with help form a nested form. The Account model have two fields name and account_admin. When the the initial user creates it's Account I want to set account_admin to the users id. But I can't get this to work.
The models is set up like this:
class Account < ActiveRecord::Base
attr_accessible :name, :account_admin
validates_presence_of :name
has_many :projects, dependent: :destroy
has_many :collaborators
has_many :users, through: :collaborators
end
class User < ActiveRecord::Base
has_secure_password
attr_accessible :email, :name, :password, :password_confirmation, :accounts_attributes
has_many :collaborators
has_many :accounts, through: :collaborators
accepts_nested_attributes_for :accounts
[...]
The UserController looks like this:
def new
if signed_in?
redirect_to root_path
else
#user = User.new
# Here I'm currently trying to set the account_admin value, but it seems to be nil.
account = #user.accounts.build(:account_admin => #user.id)
end
end
I have also tried to move account = #user.accounts.build(:account_admin => #user.id) to the create action, but the the field disappears from the form.
What would be the appropriate way to accomplish what I want (set account_admin to the users id when it is getting created)? Or is there a better approach to find out which user created the account (ie. do something with the relationship table)?
Update
With help from #joelparkerhenderson I think I got it to work. I made a method in my User model that looks like this:
def set_account_admin
account = self.accounts.last
if account.account_admin == nil
account.account_admin = self.id
account.save
end
end
Which I call with after_create :set_account_admin. This works, but is there a more "Rails way" to do the same?
Thanks.
When you call #new, the user doesn't have an id yet (it is nil).
When you #save the user, Rails automatically gives the user a new id.
You can then use the after_create Active Record callback to set the new Account's account_admin

Resources