Проблема Rails 3 с best_in_place и вложенными атрибутами

Я немного новичок в Rails, и у меня возникают проблемы с определением проблемы.

Я использую Rails 3.2.13 со следующими гемами (в дополнение к гемам по умолчанию):

gem 'devise'
gem 'cancan'
gem 'cocoon'
gem 'best_in_place'

Я использую кокон для работы с вложенными моделями, в этом случае у меня есть (разрабатывающий) пользователь, который has_many выполняет проекты, а каждый проект has_many задачи.

Я могу получить всю информацию для отображения (и сделать ее доступной для редактирования при нажатии) с помощью:

<% @project.tasks.each do |task| %>
<%= best_in_place task, :description, :path => tasks_path, :type => :input %>
<% end %>

Моя проблема в том, что я не могу получить best_in_place для сохранения обновлений моих вложенных атрибутов задач.

Модель проекта:

class Project < ActiveRecord::Base
  belongs_to :user

  has_many :tasks

  attr_accessible :description, :name, :tasks_attributes, :user_id, :tasks
  accepts_nested_attributes_for :tasks, :reject_if => :all_blank, :allow_destroy => true
end

Модель задачи:

class Task < ActiveRecord::Base
  belongs_to :project

  attr_accessible :description, :done, :hours
end

Контроллер проекта:

class ProjectsController < ApplicationController
  before_filter :authenticate_user!

  def show
    @project = Project.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render :json => @project }
    end
  end

def update
  @project = Project.find(params[:id])

    respond_to do |format|
      if @project.update_attributes(params[:project])
        format.html { redirect_to @project, :notice => 'Project was successfully updated.' }
        #format.json { head :no_content }
        format.json { respond_with_bip(@project) }
      else
        format.html { render :action => "edit" }
        #format.json { render :json => @project.errors, :status => :unprocessable_entity }
        format.json { respond_with_bip(@project) }
      end
    end
  end
end

Проекты -> show.html.erb:

<% @project.tasks.each do |task| %>
  <li class="module-list-item ui-state-default clear">
    <section class="task-name left">
      <%= best_in_place task, :description, :path => tasks_path, :type => :input %>
    </section>
  </li>
<% end %>

person JBellah    schedule 26.07.2013    source источник
comment
что у вас в params [] при обновлении? возможно, best_in_place отправляет неправильные параметры, вероятно, ничего в params [: project] и update_attributes (params [: project]) не работает   -  person stef    schedule 02.08.2013


Ответы (2)


Хотя это использование официально не поддерживается (как указывает @Ich), есть обходной путь. Никаких дополнительных контроллеров не требуется. Вам просто нужно передать param параметр в best_in_place.

class Unicycle < AR::Base
  has_one :wheel
  accepts_nested_attributes_for :wheel, update_only: true
end

best_in_place unicycle.wheel, :last_rotation, 
  path: unicycle_path(unicycle.id), type: :input, 
  param: "unicycle[wheel_attributes]"

Обратите внимание, что это немного сложнее для Car, который has_many :wheels (или для Unicycle, что has_one :wheel, где update_only вам не подойдет).

car.wheels.each do |wheel|
  best_in_place wheel, :last_rotation, 
    path: car_path(car.id), type: :input, 
    param: "car[wheel_attributes][id]=#{wheel.id}&car[wheel_attributes]" 
    # Note that you have to pass the ID of the wheel in this case
end

Работает с v3.0.3, возможно, и с гораздо более ранними версиями, но я не тестировал.

person Isaac Betesh    schedule 11.05.2015

Согласно https://github.com/bernat/best_in_place/issues/51, это не поддерживается best_in_place.

Автор драгоценного камня утверждает, что редактирование на месте должно изменять только атрибуты одной модели, поэтому изменение атрибутов другой модели не входило в область действия.

Мое мнение: Лично я сожалею об этом решении.

person Ich    schedule 19.03.2014