2013-10-25 4 views
2

레일스 4에 있습니다. House, ColorHouseColoring의 세 가지 모델이 있다고 가정 해 봅니다.레일 4의 AJAX를 통해 폼에 필드를 추가하는 방법은 무엇입니까?

class House < ActiveRecord::Base 
    has_many :house_colorings 
    has_many :colors, through: :house_colorings 
    accepts_nested_attributes_for :house_colorings, allow_destroy: true 
end 

class Color < ActiveRecord::Base 
    has_many :house_colorings 
    has_many :houses, through: :house_colorings 
end 

class HouseColoring < ActiveRecord::Base 
    belongs_to :house 
    belongs_to :color 
end 

houses_controller.rb :

<%= f.collection_select :color_id, Color.all, :id, :name, {include_blank: "Select color"} %> 
:

여기
class HousesController < ApplicationController 
    before_action :set_house 
    ... 

    def new 
    @house = House.new 
    @house.house_colorings.build 
    end 

    def create 
    @house = House.create(house_params) 
    if @house.save 
     redirect_to @house 
    else 
     render 'new' 
    end 
    end 

    def edit 
    #Gets @house from set_house 
    end 

    def update 
    if @house.update(house_params) 
     redirect_to @house 
    else 
     render 'edit' 
    end 
    end 

    ... 

    private 

    def set_house 
     @house = House.find(params[:id]) 
    end 

    def house_params 
     params.require(:house).permit(:some_parameters, house_colorings_attributes: [:id, :color_id]) 
    end 
end 

내 집 newedit

<%= form_for @house do |f| %> 
    <div id="house_colorings"> 
    <%= f.fields_for :house_colorings do |c| %> 
     <%= render "house_colorings", f: c %> 
    <% end %> 
    <%= link_to "Add color", add_color_path, remote: true %> 
</div> 
<% end %> 

_house_colorings.html.erb_form.html.erb 부분입니다 houses_controller에서

이, 내가 추가 한 :

def add_color 
    respond_to do |format| 
    format.js 
    end 
end 

add_color.js.erb :

$("#house_colorings").append("<%= escape_javascript render 'house_colorings', f: c %>"); 

내가 내 add_color 방법에 대한 경로를 추가 :

GET "/add_color" => "houses#add_color" 

add color 링크를 클릭 , 화면에는 아무 것도 나타나지 않지만 내 기록에는 500 internal server error이 표시됩니다.

Started GET "/add_color" for 127.0.0.1 at 2013-10-26 21:11:41 -0700 
Processing by HousesController#add_color as JS 
    Rendered houses/add_color.js.erb (11.3ms) 
Completed 500 Internal Server Error in 14ms 

ActionView::Template::Error (undefined local variable or method `f' for #<#<Class:0x007fc317428538>:0x007fc31710d060>): 
    1: $("#house_colorings").append("<%= escape_javascript render 'house_colorings', f: c %>"); 
    app/views/houses/add_color.js.erb:1:in `_app_views_houses_add_color_js_erb__1847085463095078116_70237941180700' 

현재로서는 내 집에 house_coloring을 추가 할 수있는 필드가 하나뿐입니다. 일부 아약스를 추가하고 거기에있는 필드 다음에 새 필드를 추가하는 링크가 있지만 그 방법을 잘 모르겠습니다.

Railscasts의 "Nested model form"을 살펴보고 지금까지의 부분을 사용했습니다. 가능한 경우 레일에서 제공하는 "data_remote"도우미를 사용하고 싶습니다. 내 질문을 편집하고 내 색상 추가 링크를 클릭 할 때 나타나는 오류에 대한 로그를 포함했습니다. 나는 내 집 컨트롤러에서 add_color.js.erb 또는 add_color 액션을 변경해야한다고 확신합니다.

제안 사항?

답변

3

음, 여기에 몇 가지 대안이 있습니다.

  1. 중첩 된 모델 형태의 railscasts의 정보 사용 Part 1

  2. 사용 Part 2 FormObject 패턴이 텟 조금 중첩 쉽게 할 수 있습니다. 패턴은 12 개 장소에서 설명되며 on railscasts (구독 필요)입니다.

  3. Angular와 같은 js 프레임 워크를 사용하십시오.js를 사용하여 클라이언트 측에 새로운 필드를 추가 할 수 있습니다. Angular.js도 railscast (구독 필요)로 덮여 있으며 매우 풍부합니다. documentation입니다.

오류가 거의 그것 모두를 알려줍니다 UPDATE. c 개체를 양식 작성기 개체로 부분에 보냅니다. houses#add_color 작업에서 인스턴스를 생성하지 않은 것으로 보입니다.

+0

응답 해 주셔서 감사합니다. "중첩 모델 양식"railscasts를 살펴보고 지금까지의 요점을 파악하기 위해 일부를 사용했지만 가능한 경우 레일로 제공되는 "data_remote"도우미를 사용하고 싶습니다. 내 질문을 편집하고 내 '색상 추가'링크를 클릭 할 때 발생하는 오류 로그를 포함했습니다. 내 집 컨트롤러에서'add_house_coloring.js.erb' 또는'add_house_coloring' 액션을 변경해야한다고 확신합니다. – oobie11

+0

@ oobie11'f : c' 대신'locals : {f : c}'를 사용하는 것이 더 낫습니다. – Almaron

+0

도와 주셔서 감사합니다. 내'add_color.js.erb'와'_form.html.erb' 모두에서'f : c'를'locals : {f : c} '로 바꾸려고했는데,'_form.html.erb'에서 따로 따로 사용했습니다. 내 기록. 다른 아이디어? – oobie11

0

체크 아웃이 두 ​​railscasts 에피소드 :

Nested Forms 1

Nested Forms 2

제 2 회 하나가 정확히 무엇을 찾고 있는지 심도있게 설명합니다.

+0

감사합니다. 나는이 코드를 점검했지만 레일 4에 있습니다. 따라서 "중첩 된 양식 2"는 가치가 떨어지는 코드가 많습니다. – oobie11

+0

더 이상 사용되지 않는 코드에는 대안이 있으므로 경고 및 리펙터를 따르십시오. – Almaron