简体   繁体   English

Rails - 一种形式到两种模式

[英]Rails - one form to two models

I am building a form in Rails (version 4.2.5) to collect basic information about stores, and I would like to have the form submit data to two separate models - one called Store, which collects information about the store, and one called Address, which just holds the address info. 我正在Rails(版本4.2.5)中构建一个表单来收集有关商店的基本信息,我希望将表单提交给两个单独的模型 - 一个名为Store,它收集有关商店的信息,一个名为Address ,它只保存地址信息。 I've seen this question floating around Stack and elsewhere, but I'm pretty new to Rails and could use a little more step-by-step guidance. 我已经看到这个问题浮在Stack和其他地方,但我对Rails很新,可以使用更多的逐步指导。 (Also, I'm aware of the Rails geocoder gem, but don't want to use it in this project despite the fact that I am collecting address and lat/long info) (另外,我知道Rails地理编码器的宝石,但不想在这个项目中使用它,尽管我正在收集地址和纬度/长信息)

For starters, here are my Store and Address models... 对于初学者,这是我的商店和地址模型......

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

class Address < ActiveRecord::Base
  belongs_to :store
end

and my StoresController... 和我的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

Finally, the form for creating a new store (not including address)... 最后,创建新商店的表格(不包括地址)......

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

So the finished form will pass the above fields to the Store model, and should also include fields for street, city, state, and zip, which are the fields that will be passed to the Address model. 因此,完成的表单将上述字段传递给Store模型,还应包括street,city,state和zip的字段,这些字段将传递给Address模型。

Overall, what is the best approach for this? 总的来说,最好的办法是什么?

And, as a follow-up question, my Address model has a column for store_id - will this column populate automatically with the id for the store as it is being created if both Store and Address models are being populated from the same form? 并且,作为后续问题,我的地址模型有一个store_id列 - 如果正在创建存储和地址模型从同一表单填充,此列是否会自动填充商店的ID? Or am I getting way out of my league here? 还是我在这里退出了联盟?

Thank you. 谢谢。

You can use accept_nested_attributes_for :address in the Store model, and then instantiate the addres form with fields_for 您可以在Store模型中使用accept_nested_attributes_for :address ,然后使用fields_for实例化fields_for

Something like this: 像这样的东西:

class Store < ActiveRecord::Base
  has_one :address
  accept_nested_attributes_for :address
end

class StoresController < ApplicationController

  def new
    @store = Store.new
    @store.build_address
  end
end

<%= form_for @store do |f| %>
  <%= f.fields_for @store.address do |ff| %>

You also need to whitelist address_attributes in the StoreController and save the address once the Store object is saved. 您还需要在StoreController中将address_attributes列入白名单,并在保存Store对象后保存地址。

You'll be best looking into accepts_nested_attributes_for : 您最好关注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 %>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM