title: Ruby on Rails ActiveRecord data flow
body: <p>I'm currently trying to build an application that works similar to something like <a href="https://trello.com/" rel="nofollow noreferrer">Trello</a>. I have <code>users</code> that can create <code>boards</code>. Each user can have a different <code>role</code> depending on what board they are on. Because I'm fairly new to Rails, I just want to make sure that I'm following the "Rails way" and best practices. Here is my schema:</p>
  
  <pre><code>create_table "boards", force: :cascade do |t|
      t.string "title"
      t.datetime "created_at", null: false
      t.datetime "updated_at", null: false
    end
  
    create_table "user_boards", force: :cascade do |t|
      t.integer "user_id"
      t.integer "board_id"
      t.integer "role"
      t.datetime "created_at", null: false
      t.datetime "updated_at", null: false
    end
  
    create_table "users", force: :cascade do |t|
      t.string "name"
      t.datetime "created_at", null: false
      t.datetime "updated_at", null: false
      t.string "email", default: "", null: false
      t.string "encrypted_password", default: "", null: false
      t.string "reset_password_token"
      t.datetime "reset_password_sent_at"
      t.datetime "remember_created_at"
      t.integer "sign_in_count", default: 0, null: false
      t.datetime "current_sign_in_at"
      t.datetime "last_sign_in_at"
      t.inet "current_sign_in_ip"
      t.inet "last_sign_in_ip"
      t.index ["email"], name: "index_users_on_email", unique: true
      t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
    end
  
    add_foreign_key "lists", "boards"
  </code></pre>
  
  <p>As you can see, I added the <code>role</code> attribute to the <code>UserBoard</code> join table. A <code>User has_many Boards</code> &amp; <code>Board has_many Users</code> both <code>through: UserBoard</code>. Depending on the <code>User</code> &amp; <code>Board</code> they can have a different <code>role</code>.</p>
  
  <p>user_board.rb</p>
  
  <pre><code>class UserBoard &lt; ApplicationRecord
    belongs_to :user
    belongs_to :board
    enum role: { admin: 0, member: 1 }
  end
  </code></pre>
  
  <p>user.rb</p>
  
  <pre><code>class User &lt; ApplicationRecord
    has_many :user_boards
    has_many :boards, through: :user_boards
    # Include default devise modules. Others available are:
    # :confirmable, :lockable, :timeoutable and :omniauthable
    devise :database_authenticatable, :registerable,
           :recoverable, :rememberable, :trackable, :validatable
    validates :name, presence: true, length: { maximum: 50 }
    validates :email, presence: true
  end
  </code></pre>
  
  <p>board.rb</p>
  
  <pre><code>class Board &lt; ApplicationRecord
    has_many :user_boards
    has_many :users, through: :user_boards
    has_many :lists, dependent: :destroy
    include AssociateUsersToBoards
  
    def self.assign_board_to_user(user, board)
      AssociateUsersToBoards.build_association(user, board)
    end
  end
  </code></pre>
  
  <p>I'm just trying to figure if this is the best way to handle this &amp; if there is a better way to set it up so that my queries &amp; updates can be a bit cleaner. Right now when a <code>User</code> creates a <code>Board</code> you can see that I'm using the <code>ActiveRecord:create</code> function. The reason as to why I'm using <code>create</code> is because when I try to use <code>new</code> or <code>build</code> the association in the join table doesn't get made. That seems wrong to me that I would not be able to perform <code>current_user.boards.new(board_params)</code> or <code>current_user.boards.build(board_params)</code>:</p>
  
  <pre><code>def create
    @board = current_user.boards.new(board_params)
  
    respond_to do |format|
      if current_user.save
        format.html { redirect_to @board, notice: 'Board was successfully created.' }
        format.json { render :show, status: :created, location: @board }
      else
        format.html { render :new }
        format.json { render json: @board.errors, status: :unprocessable_entity }
      end
    end
  end
  </code></pre>
  
  <p>But I also want to set the <code>role</code> to <code>admin</code>.. The only way I can think of doing this is <code>current_user.user_boards.find_by(board_id:@board).update_attribute(:role, 'admin')</code> after I have saved my record in my <code>board#create</code> action. This query kinda makes me want to vomit &amp; I cannot believe that there isn't a better approach.</p>
  
  <p>My <code>board_params</code> are very simple &amp; just allow the basic title:</p>
  
  <pre><code>def board_params
    params.require(:board).permit(:title)
  end
  </code></pre>
  
  <hr>
  
  <h2>EDIT</h2>
  
  <hr>
  
  <p>I also wanted to add the form I'm using to submit the <code>board</code> to make sure there isn't something wrong within that:</p>
  
  <pre><code>&lt;div class="modal-body"&gt;
    &lt;%= form_with(model: board, local: true) do |form| %&gt;
      &lt;% if board.errors.any? %&gt;
        &lt;div id="error_explanation"&gt;
          &lt;h2&gt;&lt;%= pluralize(board.errors.count, "error") %&gt; prohibited this board from being saved:&lt;/h2&gt;
  
          &lt;ul&gt;
            &lt;% board.errors.full_messages.each do |message| %&gt;
              &lt;li&gt;&lt;%= message %&gt;&lt;/li&gt;
            &lt;% end %&gt;
          &lt;/ul&gt;
        &lt;/div&gt;
      &lt;% end %&gt;
  
      &lt;div class="form-group"&gt;
        &lt;%= form.label :title %&gt;&lt;br/&gt;
        &lt;%= form.text_field :title, autofocus: true, class: 'form-control' %&gt;
      &lt;/div&gt;
  
      &lt;div class="actions"&gt;
        &lt;%= form.submit 'Create Board', class: 'btn btn-small btn-success btn-block' %&gt;
      &lt;/div&gt;
    &lt;% end %&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>All suggestions, tips and constructive criticism is very much appreciated as I try to learn/familiarize myself more &amp; more w/ the Ruby language &amp; Rails framework. </p>