Rails - 一种形式到两种模式 [英] Rails - one form to two models

查看:163
本文介绍了Rails - 一种形式到两种模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Rails(版本4.2.5)中构建一个表单来收集关于商店的基本信息,并且我希望将表单提交给两个独立的模型 - 一个叫做Store,它收集有关商店的信息,以及一个叫做地址,它只是保存地址信息。我在Stack和其他地方看到过这个问题,但我对Rails很陌生,可以使用更多一步一步的指导。 (另外,我知道Rails地理编码器gem,但不想在这个项目中使用它,尽管我收集地址和lat / long信息)

对于初学者来说,这里是我的商店和地址模型...

  class Store< ActiveRecord :: Base 
belongs_to:用户
belongs_to:store_type
has_one:地址
结束

类地址< ActiveRecord :: Base
belongs_to:store
end

和我的StoresController .. 。

  class StoresController< ApplicationController 

def new
@store = Store.new
@storeType = StoreType.all
结束

def创建
@store = Store.new(store_params)
@ store.user = current_user
$ b如果@ store.save
flash [:notice] =新建商店
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

最后,创建新商店的表单(不包括地址)...

 <%= form_for @store do | f | %GT; 

<%= 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:笔记%>
<%= f.text_field:笔记%>
< / div>

< div class =actions>
<%= f.submit:提交%>
< / div>
<%end%>

因此,完成的表单会将上述字段传递给Store模型,并且还应包含街道,城市,州和邮政编码,这些字段将被传递给地址模型。



总体而言,最好的方法是什么?



另外,作为一个后续问题,我的Address模型有一个store_id列 - 这个列会自动填充商店的id,因为它正在创建,如果Store和Address模型正在从相同的形式填充?或者我在这里得到了我的联盟吗?



谢谢。

解决方案

您最好查看 accepts_nested_attributes_for

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

#app / controllers / stores_controller.rb $ b $ class StoresController< ApplicationController
def new
@store = current_user.stores.new
@ store.build_address
end
$ b def创建
@store = current_user .stores.new store_params
@ store.save
结束

私人

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

#app / views / stores / new。 html.erb
<%= form_for @store do | f | %GT;
<%= f.fields_for:address do | a | %GT;
<%= a.text_field:line_1%>
<%end%>
<%= f.submit%>
<%end%>


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. 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. (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)

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...

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.

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? Or am I getting way out of my league here?

Thank you.

解决方案

You'll be best looking into 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 %>

这篇关于Rails - 一种形式到两种模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆