Próbuję pozwolić użytkownikowi stworzyć ćwiczenia z wyposażeniem i mięśniami w wielu do wielu relacjach za pośrednictwem odpowiednich tabel łączących (ACRICTE_PITE, Ćwiczenia_masteli). Dostałem formę pracującą do dodawania jednego sprzętu / mięśnia na ćwiczenia, ale nie można dowiedzieć się, jak dodać link, aby dodać kolejne pole do formularza w locie.

Sprawdziłem Railscast, This post zapytaliśmy o to jako pytanie boku na a , ale po prostu nie mogę uzyskać tej funkcji praca. Jestem dość nowy, aby poręczy 4 i nadal próbuję nauczyć się JavaScript, ale bardzo chciałbym, aby wyjaśnić to, jak ustawić to kolejowe szyny 4!

moje modele:

# id        :integer
# name      :string
# is_public :boolean
Exercise
    has_many :exercise_equipment
    has_many :equipment, :through => :exercise_equipment
    accepts_nested_attributes_for :exercise_equipment


# id           :integer
# exercise_id  :integer
# equipment_id :integer
# optional     :boolean
ExerciseEquipment
    belongs_to :exercise
    belongs_to :equipment
    accepts_nested_attributes_for :equipment


# id   :integer
# name :string
Equipment
    has_many :exercise_equipment
    has_many :exercises, :through => :exercise_equipment

Moje metody kontrolera:

def new
  @exercise = Exercise.new
  @exercise.exercise_equipment.build
  @exercise.exercise_muscles.build
end

def create
  exercise = current_user.exercises.new( exercise_params )
  if exercise.save!
    redirect_to exercise
  else
    render 'new'
  end
end

Wyświetlenia / Ćwiczenia / new.html.erbrb

<h1>Create New Exercise</h1>

<%= form_for @exercise do |f| %>
  <%= render 'form', f: f %>
  <%= f.submit "New Exercise" %>
<% end %>

Widoki / Ćwiczenia / _form.html.erb

<%= f.label :name %><br />
<%= f.text_field :name, autofocus: true %>

<%= f.check_box :is_public %> Public

<%= f.fields_for :exercise_muscles do |emf| %>
  <%= emf.collection_select :muscle_id, Muscle.all, :id, :name, { include_hidden: false } %>
<% end %>

<%= f.fields_for :exercise_equipment do |eef| %>
  <%= eef.collection_select :equipment_id, Equipment.all, :id, :name, { include_hidden: false } %>
  <%= eef.check_box :optional %> Optional
<% end %>
1
s_dolan 15 sierpień 2014, 03:13

2 odpowiedzi

Najlepsza odpowiedź

Po próbie użycia rozwiązania Richa chciałem znaleźć taki, który był nieco bardziej minimalny pod względem używanego kodu. Znalazłem klejnot Cocoon, który działa świetnie i był bardzo prosty do integracji.

Mój główny widok:

<div class="form-group">
  <%= f.label :name %><br />
  <%= f.text_field :name, autofocus: true %>
</div>

<div class="form-group">
  <%= f.check_box :is_public %> Public
</div>

<div class="form-group">
  <%= f.fields_for :exercise_muscles do |emf| %>
    <%= render 'exercise_muscle_fields', :f => emf %>
  <% end %>
  <%= link_to_add_association 'Add Muscle', f, :exercise_muscles %>
</div>

<div class="form-group">
  <%= f.fields_for :exercise_equipment do |eef| %>
    <%= render 'exercise_equipment_fields', :f => eef %>
  <% end %>
  <%= link_to_add_association 'Add Equipment', f, :exercise_equipment %>
</div>

Jak widać tutaj, dodanie metody prostego "link_to_add_sociation" zajmuje się wszystkimi javascript w tle. Dla przyszłych czytelników, oto częściowe, że każda z tych grup form zawiera:

_erekise_muscle_fields:

<%= f.collection_select :muscle_id, Muscle.all.order( 'muscle_group_id ASC' ), :id, :name, { include_hidden: false } %>

_exercise_equipment_fields:

<%= f.collection_select :equipment_id, Equipment.all.order( 'name ASC' ), :id, :name, { include_hidden: false } %>
<%= f.check_box :optional %> Optional
1
s_dolan 20 sierpień 2014, 18:31

Ajax

Nie można dowiedzieć się, jak dodać link, aby dodać kolejne pole do formularza w locie

"Droga kolejowa", która ma być "ciągnięciem" nowej instancji bloku {X0}} z żądania ajax.

Powodem, dla którego zalecana jest Ajax, jest to, że jest to "szyna sposób", aby to zrobić - całkowicie modułowe i rozszerzalne:

#config/routes.rb
resources :exercises do
   get :add_field, on: :collection
end

#app/models/exercise.rb
Class Exercise < ActiveRecord::Base
   ...
   def self.build #-> allows you to call a single method
      exercise = self.new
      exercise.exercise_equipment.build
      exercise.exercise_muscles.build
      return
   end
end

#app/controllers/exercises_controller.rb
Class ExercisesController < ApplicationController
   def add_field
      @exercise = Exercise.build
      respond_to do |format|
         format.html
         format.js
      end
   end
end

#app/views/exercises/new.html.erb
<%= form_for @exercise do |f| %>
   <%= render "fields", locals: { f: f } %>
   <%= f.submit %>
<% end %>

#app/views/exercises/add_field.js.erb
$("#form_element").append("<%=j render "exercises/form", locals: { exercise: @exercise } %>");

#app/views/exercises/_form.html.erb
<%= form_for exercise do |f| %>
   <%= render "fields", locals: { f: f } %>
<% end %>

#app/views/exercises/_fields.html.erb
<%= f.fields_for :exercise_muscles, child_index: Time.now.to_i do |emf| %>
    <%= emf.collection_select :muscle_id, Muscle.all, :id, :name, { include_hidden: false } %>
<% end %>
<%= link_to "New Field", exercises_add_fields_path, remote: :true %>

<%= f.fields_for :exercise_equipment, child_index: Time.now.to_i do |eef| %>
   <%= eef.collection_select :equipment_id, Equipment.all, :id, :name, { include_hidden: false } %>
   <%= eef.check_box :optional %> Optional
<% end %>
<%= link_to "New Field", exercises_add_fields_path, remote: :true %>

Daje to możliwość tworzenia pól przez połączenie AJAX; który jest właściwy sposobem na to

2
Richard Peck 15 sierpień 2014, 11:34