2013-10-25 1 views
2

Я на Rails 4. Предположим, у меня есть три модели: House, Color и HouseColoring.Как добавить дополнительное поле в форму через AJAX в rails 4?

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:

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 

Вот мой _form.html.erb парциальное для моего дома new и edit

<%= 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:

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

В 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 в мой дом. Я хочу добавить ajax и иметь ссылку в моей форме, которая добавляет новое поле после того, которое есть, но я не уверен, как это сделать.

Я прошел через «Вложенную модельную форму» из Railscasts и использовал их части, чтобы добраться до точки, которой я являюсь сейчас, но я хотел бы использовать «data_remote» помощники, предоставляемые рельсами, если можно. Я отредактировал свой вопрос и включил журнал ошибок, которые получаю, когда я нажимаю ссылку добавить цвет. Я уверен, что мне нужно изменить либо мое add_color.js.erb, либо действие add_color в моем контроллере домов.

Любые предложения?

ответ

3

Ну, у вас есть пара альтернатив здесь.

  1. Используйте информацию в Вложенные модели формы Railscasts: Part 1 и Part 2

  2. Используйте FormObject шаблон, чтобы сделать Тхет вложенности немного легче. Шаблон описан в десятке мест, а также on railscasts (подписка необходима).

  3. Используйте фреймворк 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 Кажется, вам лучше использовать 'locals: {f: c}' вместо просто 'f: c' – Almaron

+0

Спасибо, что помогли мне с этим. Я попытался заменить 'f: c' на' locals: {f: c} 'как на мои' add_color.js.erb', так и на my '_form.html.erb' отдельно и вместе, и я все равно получаю такую ​​же ошибку 500 в мой журнал. Любые другие идеи? – oobie11

0

Проверьте эти два Railscasts эпизод:

Nested Forms 1

Nested Forms 2

2-й один объясняет глубину, что вы точно ищете.

+0

Спасибо, я проверил их, но я на рельсах 4, поэтому «Вложенные формы 2» имеет много обесцененного кода. – oobie11

+0

Все эти устаревшие коды имеют альтернативы, поэтому просто следуйте предупреждениям и рефактору) – Almaron