Assigning id's from another table to input using nested forms in Rails 4 -


i'm few weeks in first experience rails / web development in general , have come across snag can't seem find on overflow or work out. feel i'm there not quite...

i'm developing staff site charity, , need categorize new staff members in order assign privileges each of them. currently, have staff new view creates new staff members, , have nested form type in add staff's department @ same time. however, @ moment new department generated every new member of staff. if created 2 staff department "admin", end 2 admin departments separate type_id's instead of them being assigned same. how assign staff's type/department create in form, assuming departments exist. in console this:

s = staff.create(staff_name: "john", staff_email: "john@example.com", password: "asdsadsad") t = type.create(department: "admin") s.types << t 

so far models staff , types(categories) (irrelevant parts removed), in i've added accepts_nested_attributes_for:

class staff < activerecord::base   has_many :staff_types   has_many :types, through: :staff_types   accepts_nested_attributes_for :types   validates :staff_name, presence: true, length: { minimum: 5, maximum: 50}   has_secure_password end  class stafftype < activerecord::base   belongs_to :staff   belongs_to :type end  class type < activerecord::base   validates :department, presence: true, length: { minimum: 2, maximum: 25 }   has_many :staff_types   has_many :staffs, through: :staff_types end 

my staff controller, in i've whitelisted type variables, follows:

class staffscontroller < applicationcontroller   before_action :set_staff, only: [:edit, :update, :show]    def new     @staff = staff.new     1.times { @staff.types.build}   end     def create     @staff = staff.new(staff_params)     if @staff.save       flash[:success] = "your account has been created successfully"       redirect_to staff_path(@staff)     else       render 'new'     end   end    private    def staff_params     params.require(:staff).permit(:staff_name, :staff_email, types_attributes: [:id, :department])   end end 

and view following, in i've embedded nested form in form_for helper:

<div class="row">    <div class="well col-md-8 col-md-offset-2">      <%= form_for @staff |f| %>         <%= f.label :staff_name %>        <%= f.text_field :staff_name %>         <%= f.label :staff_email %>        <%= f.email_field :staff_email %>         <%= f.label :password %>        <%= f.password_field :password %>         <%= f.label :password_confirmation %>        <%= f.password_field :password_confirmation %>         <%= f.fields_for :types, @staff.types |types_form| %>          <%= types_form.label :department %>          <%= types_form.text_field :department %>        <% end %>         <%= f.submit(@staff.new_record? ? "submit profile" : "submit edited profile", class: "btn btn-success") %>     <% end %>   </div> </div> 

the reason new record created every time submit new staff member because don't let controller know staff member's type existing type. question is, best way go doing edit sentence

method #1: choose staff member types in multi-select

if have set number of types, you've inserted them, , don't need change them, can use multi-select. so, replace below code in code...

<%= f.fields_for :types, @staff.types |types_form| %>   <%= types_form.label :department %>   <%= types_form.text_field :department %> <% end %> 

...with:

<%= f.collection_select :type_ids, type.all, :id, :department,     { selected: @staff.type_ids }, { multiple: true, size: type.all.size } %> 

and then, in controller, change staff_params method to:

def staff_params   params.require(:staff).permit(:staff_name, :staff_email, type_ids: []) end 

using method, you'll able select multiple types each staff member out of possible types. assuming don't need create type when create staff member, i'd recommend going forward member.

you can use checkboxes rather multi-select, won't cover in answer. can read check boxes here.

method #2: determine types new in controller

if you'd keep ability type in staff member's type, it'll bit trickier, think can keep of logic in create method of controller. currently, in method, save staff member grab parameters it. can first check if of types passed new (i.e. staff member hasn't yet been associated type), , if @ least 1 is, check if each existing type. update create method read:

def create   @staff = staff.assign_attributes(staff_params)    @staff.staff_types.each_with_index |staff_type, index|     if (type = type.find_by(department: staff_type.type.department)).present?       @staff.staff_type[index].assign_attribute(:id, type.id)     end   end    if @staff.save     flash[:success] = "your account has been created successfully"     redirect_to staff_path(@staff)   else     render 'new'   end end 

i should note there better way this, , answer encourages post better one, answer should work purposes.


Comments

Popular posts from this blog

php - failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request -

java - How to filter a backspace keyboard input -

java - Show Soft Keyboard when EditText Appears -