Search code examples
ruby-on-railsrubyhas-many-through

How to modify nested params in Rails?


I am working on similar app.I have 3 models: User, Group and Relation.I want to make a form where a logged in user can create a group and invite a college(other user registered in db).I am using has_many through association.Here are these models:

class Group < ApplicationRecord
  has_many :relations
  has_many :users, through: :relations

  accepts_nested_attributes_for :relations
end 

class Relation < ApplicationRecord
  belongs_to :group
  belongs_to :user
end

class User < ApplicationRecord
  attr_accessor :remember_token


  has_many :transactions, dependent: :destroy
  has_many :relations
  has_many :groups, through: :relations
  <some validation >

end

My GroupsController

class GroupsController < ApplicationController

  def new
    @group = Group.new
    @group.relations.build
  end
  
  def create
    @group = Group.new(groups_params)
    if @group.save
      flash[:success] = "Group has been created!"
      redirect_to root_path
    else  
      flash[:danger] = "Something went wrong!"
      render 'groups/new'
    end 
  end 


  private
  def groups_params
    params.require(:group).permit(:group_name, :group_from, :group_to, 
                                  relations_attributes: Relation.attribute_names.map(&:to_sym) )
                                  #Relation.attribute_names.map(&:to_sym) this grabs all the column names
                                  #of the relations tabel, puts it in the array and maps each element with hash
                                  #[:id, :group_id, :user_id, :created_at, :updated_at] 
  end

end

And my view for "new" action

<%= provide(:title, "New Group") %>
<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for @group do |group| %>
      <%= group.label :group_name, "Group name"%>
      <%= group.text_field :group_name %>

      <%= group.label :group_from, "Group from"%>
      <%= group.date_field :group_from %>

      <%= group.label :group_to, "Group to"%>
      <%= group.date_field :group_to %>
      <!-- :relations is a symbol for assosiation between the group and user -->
      <%= group.fields_for :relations do |relations_form| %>
        <%= relations_form.label :user_id, "Member #1" %>
        <%= relations_form.text_field :user_id %>
      <% end %>

      <%= group.submit "Create a group!" %>
    <% end %>
  </div>
</div>

screenshot: https://i.sstatic.net/u1LDX.png

With this code a logged in user is able to create group record and relation record simultaneously but it has to pass an id of user it wants to invite to a group(for example: "7" not "John" - the name of the user with id 7) What I want to achieve is to get the id of the user names pass in the "Member #1" field.Example: 1.A logged in user puts in the "Member #1" field: "John" 2.Some function to get the id of the "John" - modify params 3.if "John" exists in users tabel then save the group -> create a group record and relation record.

I think I have to modify nested params, but I do not know how to do this. Thanks for any help, Lukas


Solution

  • Instead of an input text field, you should try out a select dropdown where you can choose the existing members. Like this it will show the name to the user but it will select the ID which will be sent to the controller.