Reputation:
I’ve setup a has_many :through association between a User and Organisation model, using a Membership model as the join.
class Organisation < ActiveRecord::Base
has_many :memberships
has_many :users, :through => :memberships
end
class User < ActiveRecord::Base
. . .
has_many :memberships
has_many :organisations, :through => memberships
end
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :organisation
end
When a User creates an organisation, I want a membership to automatically be created linking the user to that organisation.
Where is the best place to attack this?
Options I’ve been investigating:
Use an after_create callback on the organisation
Move this process into a separate Ruby class.
In the organisations Controller, create action.
?
How would you recommend I go about it?
Is there somewhere in the Rails Guides where it outlines best practices for this kind of thing?
Rails 4.2.5.
Upvotes: 1
Views: 1294
Reputation: 10398
Where is the best place to attack this?
I would like to say you should write this in OrganisationsController's
create
action to make a DRY
on update action as well(use strong parameter) .Because form attribute that you are getting is from outer worlds and it is best to use permit method
on required params
using Strong Parametre concept.
def create
@organisation = Organisation.new(organisation_params)
...
end
def organisation_params
# here you could write all the params which you want to permit from outer worlds
end
Nore more info about Strong Parameters
Upvotes: 0
Reputation: 76784
#config/routes.rb
resources :organizations #-> url.com/organizations/new
#app/controllers/organizations_controller.rb
class OrganizationsController < ApplicationController
before_action :authenticate_user!
def new
@organization = current_user.organizations.new
end
def create
@organization = current_user.organizations.new organization_params
@organization.save
end
private
def organization_params
params.require(:organization).permit(:x, :y, :z) #-> membership automatically created
end
end
The above will automatically create the associated membership; assuming you're using Devise
& have access to the current_user
method.
--
The best practice is the most succinct; there is no way you're "meant" to do it.
One of the biggest fallacies I see in Rails is people trying to find the most acceptable way to do something (as if there's a rulebook). The best thing you can do is get it working then refactor the code.
As you progress through your app, you'll find that certain patterns can be changed, some removed and many combined. The more "DRY" you make your code, the better it is (as a rule).
Upvotes: 1
Reputation: 58
If there isn't any additional logic other than creating an organization and membership, I would just do #3. However, if you are planning on adding more logic for creating a new organization in the future, I would create a new service (#2).
Upvotes: 0
Reputation: 1840
I think you should just be able to do something like:
org = Organisation.new
org.otherstuff = "populate other stuff"
org.users = [user_who_created]
org.save
After that the two should be related...? If you wanted to encapsulate this behavior you could do something like have a class method on Organization like create_org_for_user(name, user)
and then do this logic in there, or you could do it in the controller action that handles the creation.
Upvotes: 0
Reputation: 335
My idea is way 3. Normaly, when set up many - many association in models, we should do creating temp table record auto through controller.
For example in controller you can write:
@organisation = current_user.organisations.build organisation_params
if @organisation.save
....
So that if @organisation is save then after that memberships record auto generate.
You can see this tutorial to see that:
http://blog.teamtreehouse.com/what-is-a-has_many-through-association-in-ruby-on-rails-treehouse-quick-tip
Upvotes: 0