【问题标题】:Rails create/update more than one model at the same timeRails 同时创建/更新多个模型
【发布时间】:2015-07-15 19:30:40
【问题描述】:

我一直在为嵌套表单苦苦挣扎,但我不知道为什么它不起作用。

表格更新/创建场地没有投诉,但没有相关联的场地图像。

问题:我想同时创建/更新一个模型及其关联模型之一。请注意,控制器的命名空间在“admin”下

_form.haml

.col-md-12
  = form_for([:admin, venue], html: { class: 'form-horizontal', multipart: true }) do |f|
    - if venue.errors.any?
      .col-md-12.alert.alert-danger{role: "alert"}
        %h2
          = pluralize(venue.errors.count, "Error")
        %ul
          - venue.errors.full_messages.each do |message|
            %li= message
    .form-group
      = f.label :name, class: 'col-md-2 control-label'
      .col-md-10
        = f.text_field :name, class: 'form-control'
    .form-group
      = f.label :category, class: 'col-md-2 control-label'
      .col-md-10
        = f.text_field :category, class: 'form-control'
    .form-group
      = f.label :description, class: 'col-md-2 control-label'
      .col-md-10
        = f.text_area :description, rows: 5, class: 'form-control'
    .form-group
      = f.label :street, class: 'col-md-2 control-label'
      .col-md-10
        = f.text_field :street, class: 'form-control'
    .form-group
      = f.label :zip, class: 'col-md-2 control-label'
      .col-md-10
        = f.text_field :zip, class: 'form-control'
    .form-group
      = f.label :city, class: 'col-md-2 control-label'
      .col-md-10
        = f.text_field :city, class: 'form-control'
    .form-group
      = f.label :homepage, class: 'col-md-2 control-label'
      .col-md-10
        = f.url_field :homepage, class: 'form-control'
    %h3 Add images
    = f.fields_for(:venue_image, html: { class: 'form-horizontal', multipart: true }) do |vi|
      .form-group
        = vi.label :name, class: 'col-md-2 control-label'
        .col-md-10
          = vi.input :name, label: false,  class: 'form-control'
      .form-group
        = vi.label :venue_id, class: 'col-md-2 control-label'
        .col-md-10
          = vi.input :venue_id, label: false,  class: 'form-control'
      .form-group
        = vi.label :default, class: 'col-md-2 control-label'
        .col-md-10
          = vi.input :default, as: :radio_buttons, label: false, class: 'form-control radio radio-inline'
      .form-group
        = vi.label :image_file, class: 'col-md-2 control-label'
        .col-md-10
          = vi.file_field :image_file, label: false, class: 'form-control'

    .actions
      = f.submit 'Save', class: 'btn btn-primary pull-right'
      = link_to 'Cancel', :back, class: 'btn btn-default'

venues_controller

class Admin::VenuesController < Admin::BaseController
  before_action :set_venue, only: [:show, :edit, :update, :destroy]

  def index
    @venues = Venue.all
  end

  def show
  end

  def new
    @venue = Venue.new
    @venue.venue_images.build
  end

  def edit
  end

  def create
    @venue = Venue.new(venue_params)

    if @venue.save
      redirect_to admin_venue_path(@venue), notice: 'Venue was successfully created.'
    else
      render :new
    end
  end

  def update
    if @venue.update(venue_params)
      redirect_to admin_venue_path(@venue), notice: 'Venue was successfully updated.'
    else
      render edit_admin_venue
    end
  end

  def destroy
    @venue.destroy
    redirect_to admin_venues_url, notice: 'Venue was successfully destroyed.'
  end

  private

  def set_venue
    @venue = Venue.find(params[:id])
  end

  def venue_params
    params.require(:venue).permit(:name, :category, :description, :street, :zip, :city, :homepage,
                                  venue_image_attributes: [:name, :default, :image_file])
  end
end

venue_images_controller

class Admin::VenueImagesController < Admin::BaseController
  def new
    image = VenueImage.new
    render locals: { image: image }
  end

  def create
    # TODO: Remove @ if possible
    @image = VenueImage.new(venue_images_params)

    if @image.save
      redirect_to admin_venue_path(@image.venue.id), notice: 'Image was successfully created.'
    else
      render admin_new_venue_path
    end
  end

  private

  def venue_images_params
    params.require(:venue_image).permit(:name, :default, :image_file, :venue_id)
  end
end

路线

namespace :admin do
  resources :venues do
    resources :venue_images
  end
  resources :users
end

提前感谢您的帮助!如果您需要更多代码,请告诉我。

【问题讨论】:

  • 另外命名也不是很理想
  • 你的场地模型有accepts_nested_attributes_for :venue_images吗?
  • 发布此表单后,您的rails server 输出中有任何投诉吗?
  • 实际上是的:Unpermitted parameters: venue_image- 我一直都错过了。不过还是一头雾水。也许是因为:def venue_params params.require(:venue).permit(:name, :category, :description, :street, :zip, :city, :homepage, venue_image_attributes: [:name, :default, :image_file]) end 如果我将venue_image_attributes: 更改为venue_image:,它会说:unknown attribute: venue_image
  • 在您的venue_params 方法中,我认为应该是... venue_images_attributes...(将venue_image 设为复数)。这是那些有点深奥但最终合乎逻辑的 Rails 命名约定之一。

标签: ruby-on-rails forms ruby-on-rails-4


【解决方案1】:

似乎您与Venue(即has_many :venue_images)有has_many 关系,然后是这一行

= f.fields_for(:venue_image, html: { class: 'form-horizontal', multipart: true }) do |vi|

应该是

= f.fields_for(:venue_images, html: { class: 'form-horizontal', multipart: true }) do |vi|

您的venue_params 方法应该如下所示

def venue_params
 params.require(:venue).permit(:id, :name, :category, :description, :street, :zip, :city, :homepage, venue_images_attributes: [:id, :name, :default, :image_file])
end

注意复数 venue_images 并且我将 :id 添加到 venue_params 以便 更新 正常工作。

【讨论】:

  • 有趣的是:当我将 fields_for 更改为 venue_images 时,复数形式的那部分就消失了。知道为什么会这样吗?
猜你喜欢
  • 2021-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多