Rails - 一种形式到两种模型

skw*_*eth 5 forms model ruby-on-rails ruby-on-rails-4

我正在 Rails(版本 4.2.5)中构建一个表单来收集有关商店的基本信息,我希望该表单将数据提交给两个单独的模型 - 一个称为 Store,它收集有关商店的信息,另一个称为 Address ,它只保存地址信息。我在 Stack 和其他地方看到过这个问题,但我对 Rails 很陌生,可以使用更多的分步指导。(另外,我知道 Rails geocoder gem,但我不想在这个项目中使用它,尽管我正在收集地址和经纬度信息)

首先,这是我的 Store 和 Address 模型...

class Store < ActiveRecord::Base
  belongs_to :user
  belongs_to :store_type
  has_one :address
end

class Address < ActiveRecord::Base
  belongs_to :store
end
Run Code Online (Sandbox Code Playgroud)

和我的 StoresController...

class StoresController < ApplicationController

    def new
        @store = Store.new
        @storeType = StoreType.all
    end

    def create
        @store = Store.new(store_params)
        @store.user = current_user

        if @store.save
            flash[:notice] = "New store created"
            redirect_to root_path
        else
            #ERROR STUFF
        end
    end

    private
    def store_params
        params.require(:store).permit(:user_id, :store_type_id, :latitude, :longitude, :name, :notes)
    end
end
Run Code Online (Sandbox Code Playgroud)

最后是新建店铺的表格(不包括地址)...

<%= form_for @store do |f| %>

    <%= f.hidden_field :latitude, :id => "latitude_field"  %>
    <%= f.hidden_field :longitude, :id => "longitude_field"  %>

    <div class="field">
        <%= f.label :store_type_id %>
        <%= f.select :store_type_id, @storeType.map{ |type| [type.store_type.capitalize, type.id] } %>
    </div>

    <div class="field">
        <%= f.label :name %>
        <%= f.text_field :name  %>
    </div>

    <div class="field">
        <%= f.label :notes %>
        <%= f.text_field :notes  %>
    </div>

    <div class="actions">
        <%= f.submit :"Submit" %>
    </div>
<% end %>
Run Code Online (Sandbox Code Playgroud)

所以完成的表单会将上述字段传递给 Store 模型,还应该包括街道、城市、州和邮政编码的字段,这些字段将传递给 Address 模型。

总的来说,最好的方法是什么?

并且,作为一个后续问题,我的 Address 模型有一个 store_id 列 - 如果 Store 和 Address 模型是从同一表单填充的,那么该列是否会在创建商店时自动填充商店的 id?或者我在这里脱离了我的联盟?

谢谢你。

Ric*_*eck 4

你最好研究一下accepts_nested_attributes_for

#app/models/store.rb
class Store < ActiveRecord::Base
   has_one :address
   accepts_nested_attributes_for :address
end

#app/controllers/stores_controller.rb
class StoresController < ApplicationController
   def new
      @store = current_user.stores.new
      @store.build_address
   end

   def create
      @store = current_user.stores.new store_params
      @store.save
   end

   private

   def store_params
      params.require(:store).permit(:store_type_id, :latitude, :longitude, :name, :notes, address_attributes: [:line_1])
   end
end

#app/views/stores/new.html.erb
<%= form_for @store do |f| %>
   <%= f.fields_for :address do |a| %>
      <%= a.text_field :line_1 %>
   <% end %>
   <%= f.submit %>
<% end %>
Run Code Online (Sandbox Code Playgroud)