Rails 4 has_many :through relationship: assign default value to join model attribute on create action from parent model

Thibaud Clement

I have three models:

class User < ActiveRecord::Base
  has_many :administrations
  has_many :calendars, through: :administrations
end

class Calendar < ActiveRecord::Base
  has_many :administrations
  has_many :users, through: :administrations
end

class Administration < ActiveRecord::Base
  belongs_to :user
  belongs_to :calendar
end

Remark: I am using Devise for authentication on the User model.

The join Administration model has the following attributes:

  • id
  • user_id
  • calendar_id
  • role

Here are my current routes:

devise_for :users, :path => 'account'

resources :users do
  resources :calendars
end

And here is my calendars_controller:

class CalendarsController < ApplicationController
  before_action :set_calendar, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!

  # GET /calendars
  # GET /calendars.json
  def index
    @user = current_user
    @calendars = Calendar.all
  end

  # GET /calendars/1
  # GET /calendars/1.json
  def show
    @user = current_user
    @calendar = Calendar.find(params[:id])
  end

  # GET /calendars/new
  def new
    @user = current_user
    @calendar = @user.calendars.new
  end

  # GET /calendars/1/edit
  def edit
    @user = current_user
  end

  # POST /calendars
  # POST /calendars.json
  def create
    @user = current_user
    @calendar = @user.calendars.new(calendar_params)

    respond_to do |format|
      if @calendar.save
        format.html { redirect_to user_calendar_path(@user,@calendar), notice: 'Calendar was successfully created.' }
        format.json { render :show, status: :created, location: @calendar }
      else
        format.html { render :new }
        format.json { render json: @calendar.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /calendars/1
  # PATCH/PUT /calendars/1.json
  def update
    @user = current_user
    @calendar = Calendar.find(params[:id])
    respond_to do |format|
      if @calendar.update(calendar_params)
        format.html { redirect_to user_calendar_path(@user,@calendar), notice: 'Calendar was successfully updated.' }
        format.json { render :show, status: :ok, location: @calendar }
      else
        format.html { render :edit }
        format.json { render json: @calendar.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /calendars/1
  # DELETE /calendars/1.json
  def destroy
    @user = current_user
    @calendar.destroy
    respond_to do |format|
      format.html { redirect_to user_calendars_url, notice: 'Calendar was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_calendar
      @calendar = Calendar.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def calendar_params
      params.require(:calendar).permit(:name)
    end
end

My basic CRUD actions are working: once a user is logged in, he can create, show, edit and destroy a calendar that belongs to him.

What I am trying to figure out now, is how to define a default role — Owner — in the Administration join table when a user creates a new calendar.

I was considering adding the following line of code to Calendars#Create:

current_user.add_calendar_and_role(@calendar.id, 'Owner')

but I am not sure this is a good practice.

Instead, shouldn't I define a make_owner method in my administration model and use it with a callback in the Calendars#Create action?

Should I also implement accepts_nested_attributes_for in my calendar model?

Or is there an even better solution that I am forgetting about?

Mark Swardstrom

In general - move code to the model when you can. Keep your controllers simple.

I don't think you need accepts nested attributes. I tend to use that when my models are truly child objects, not just joined.

Your datamodel looks good - I think whatever you choose, you'll be able to improve it later or handle more special cases. That said, I do this sort of thing

class Administration < ActiveRecord::Base

  before_validation :set_default_role

  def set_default_role
    existing_owner = where(:calendar_id => calendar_id, :role => :owner).exists?
    if existing_owner?
      self.role ||= :standard
    else
      self.role ||= :owner
    end
  end

end

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Rails 4 has_many through: update join model from parent model edit view

From Dev

Rails 4 has_many :through relationship: destroy parent model instance when child model instance count reaches 0

From Dev

Rails 4 has_many :through association: use Devise current_user in other parent model after_create callback

From Dev

Rails 4: Being able to select multiple instances of one model when creating the model it has a has_many :through relationship with

From Dev

Rails: Create Model and join table at the same time, has_many through

From Dev

Rails 4 + Pundit : join model authorization in has_many :through association

From Dev

Rails 4 active record model has_many through associations?

From Dev

Rails 4 active record model has_many through associations?

From Dev

has_many through relationship to the same Model

From Dev

Rails 4 create model with nested attributes has_many

From Dev

How to build has_many :through relationship between the same Model (User) in Rails?

From Dev

Rails4 model ignores parent_id on 'create' action

From Dev

Rails 4 override a model attribute with parent attribute

From Dev

Rails has_many through join model undefined id: "undefined method `attributes' for #" when submitting nested form

From Dev

Rails 4 has_many through join table manage attribute increasing

From Dev

Rails field on join entity in has_many through relationship

From Dev

Rails 4+ has_many through a has one relationship?

From Dev

Rails Model relationship has_many belongs_to

From Dev

rails4 collection select with has_many through association and nested model forms

From Dev

Is a has_many through relationship possible with 4 models in rails?

From Dev

Rails - Saving a model with has_many :through association from AngularJS layer

From Dev

Rails Active Model Serializer - has_many and accessing the parent record

From Dev

Rails mutlipe has_many through different models to single model

From Dev

Rails association "has_many :through" in the same model

From Dev

Rails model multiple has_many :through relationships output to json

From Dev

rails 4 nested attributes won't create has_many model

From Dev

How to create join table record in Rails, has many: through relationship

From Dev

Nested form for has many :through join model, where join model has additional attribute

From Dev

Issue with join table and has_many through association in Rails 4

Related Related

  1. 1

    Rails 4 has_many through: update join model from parent model edit view

  2. 2

    Rails 4 has_many :through relationship: destroy parent model instance when child model instance count reaches 0

  3. 3

    Rails 4 has_many :through association: use Devise current_user in other parent model after_create callback

  4. 4

    Rails 4: Being able to select multiple instances of one model when creating the model it has a has_many :through relationship with

  5. 5

    Rails: Create Model and join table at the same time, has_many through

  6. 6

    Rails 4 + Pundit : join model authorization in has_many :through association

  7. 7

    Rails 4 active record model has_many through associations?

  8. 8

    Rails 4 active record model has_many through associations?

  9. 9

    has_many through relationship to the same Model

  10. 10

    Rails 4 create model with nested attributes has_many

  11. 11

    How to build has_many :through relationship between the same Model (User) in Rails?

  12. 12

    Rails4 model ignores parent_id on 'create' action

  13. 13

    Rails 4 override a model attribute with parent attribute

  14. 14

    Rails has_many through join model undefined id: "undefined method `attributes' for #" when submitting nested form

  15. 15

    Rails 4 has_many through join table manage attribute increasing

  16. 16

    Rails field on join entity in has_many through relationship

  17. 17

    Rails 4+ has_many through a has one relationship?

  18. 18

    Rails Model relationship has_many belongs_to

  19. 19

    rails4 collection select with has_many through association and nested model forms

  20. 20

    Is a has_many through relationship possible with 4 models in rails?

  21. 21

    Rails - Saving a model with has_many :through association from AngularJS layer

  22. 22

    Rails Active Model Serializer - has_many and accessing the parent record

  23. 23

    Rails mutlipe has_many through different models to single model

  24. 24

    Rails association "has_many :through" in the same model

  25. 25

    Rails model multiple has_many :through relationships output to json

  26. 26

    rails 4 nested attributes won't create has_many model

  27. 27

    How to create join table record in Rails, has many: through relationship

  28. 28

    Nested form for has many :through join model, where join model has additional attribute

  29. 29

    Issue with join table and has_many through association in Rails 4

HotTag

Archive