Rails表单从一个表填充并保存到另一个表

时间:2016-02-04 08:55:43

标签: ruby-on-rails

标题有点说明了一切,基本上我有这种形式

<% provide(:title, "Edit user") %>
<h1>Editing event:
  <%= @newevent.id %></h1>
<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= simple_form_for @newevent do |f| %>
    <div class="form-group">
      <%= f.label :eventname %>
      <div class="row">
        <div class="col-md-6">
          <%= f.text_field :eventname, :autofocus => true, class: "form-control" %>
        </div>
      </div>
    </div>
    <div class="form-group">
      <div class="row">
        <div class="col-md-6">
          <%= f.input :event_type, :collection => ['Concert','Festival','Sports','Theatre'] %>
        </div>
      </div>
    </div>
    <div class="form-group">
      <%= f.label :eventdesc %>
      <div class="row">
        <div class="col-md-6">
          <%= f.text_field :eventdesc, :autofocus => true, class: "form-control" %>
        </div>
      </div>
    </div>
    <div class="form-group">
      <%= f.label :eventshortdesc %>
      <div class="row">
        <div class="col-md-6">
          <%= f.text_field :eventshortdesc, :autofocus => true, class: "form-control" %>
        </div>
      </div>
    </div>
    <div class="form-group">
      <%= f.label :pagetitle %>
      <div class="row">
        <div class="col-md-6">
          <%= f.text_field :pagetitle, :autofocus => true, class: "form-control" %>
        </div>
      </div>
    </div>
    <div class="form-group">
      <%= f.label :metatag %>
      <div class="row">
        <div class="col-md-6">
          <%= f.text_field :metatag, :autofocus => true, class: "form-control" %>
        </div>
      </div>
    </div>
    <div class="form-group">
      <%= f.label :eventvenuename %>
      <div class="row">
        <div class="col-md-6">
          <%= f.text_field :eventvenuename, :autofocus => true, class: "form-control" %>
        </div>
      </div>
    </div>
    <div class="form-group">
      <div class="row">
        <div class="col-md-6">
          <%= f.input :time, type: "time", :autofocus => true, class: "form-control" %>
        </div>
      </div>
    </div>
    <div class="form-group">
      <div class="row">
        <div class="col-md-6">
          <%= f.input :date, type: "date", :autofocus => true, class: "form-control" %>
        </div>
      </div>
    </div>
    <div class="form-group">
      <%= f.label :eventimage %>
      <div class="row">
        <div class="col-md-6">
          <%= f.text_field :eventimage, :autofocus => true, class: "form-control" %>
        </div>
      </div>
    </div>
    <%= f.submit "Save changes", class: "btn btn-info" %>
<%= link_to "Delete", event_path(@newevent), :method => :delete, class: "btn btn-danger" %>
    <% end %>
  </div>
</div>

这是从中加载的内容。

  def edit
    @newevent = Event.find(params[:id])
  end

然而它现在不同了。我想要从Master表加载这些东西(所以字段是从Master填充的)但是我有一个看起来像这样的更新方法

  def update
    @newevent = Event.find(params[:id])
    if @newevent.update_attributes(event_params.merge createdby: current_user.id)
      flash[:success] = "Profile updated"
      redirect_to "/events"
    else
      flash.now[:alert] = 'Error updating event'
    end
  end

我是否需要更改eventparams中的某些内容才能使其工作(并从Event更改为Master)两个表中的字段都不同,所以我需要更改值这些领域是这样的吗?

value: "<%=Master.name%>"

谢谢

萨姆

2 个答案:

答案 0 :(得分:1)

如果您尝试加载“默认值”,则最好在模型层中执行此操作:

#app/models/event.rb
class Event < ActiveRecord::Base
   before_create :set_defaults

   private

   def set_defaults
     default = Master.first
     self.attributes.except("id", "created_at", "updated_at").each do |field|
       self[field] ||= default.send(field)
     end
   end
end 

以上内容将从Master模型中提取记录,填充attributes模型中尚未填充的任何Event

然而,我认为你的模式效率低下。

您从另一个模型/表中提取“默认”数据的想法直接与软件开发的DRYmodular原则相矛盾。

不是说如果你想为模型创建“动态”默认值,你的模式可能会起作用。如果您尝试将完全相同的数据存储在不同的模型中,则会出现问题。

我会做以下事情:

#app/models/event.rb
class Event < ActiveRecord::Base
   @@defaults: {
     x: "y",
     y: "z",
     z: "0"
   }

   before_create :set_defaults

   private

   def set_defaults
     self.attributes.except("id", "created_at", "updated_at").each do |field|
       self[field] ||= @@defaults[field]
     end      
   end
end

<强>更新

经过讨论后,很明显需要更多的上下文来完全理解问题/解决方案。

该应用程序的工作原理是将一系列CSV数据导入Master表。虽然我不知道这是什么数据,但OP表示每个Event将围绕 Master中的数据构建。

他提到他绝对需要来自Master 3 字段,而其他字段可由用户输入Event

这意味着您可以将两者结合在一起has_many / belongs_to关系:

#app/models/master.rb
class Master < ActiveRecord::Base
   has_many :events
end

#app/models/event.rb
class Event < ActiveRecord::Base
   belongs_to :master
end

这是一个标准ActiveRecord association,这意味着您可以致电@master.events&amp; @event.master - 访问每个表中的值:

#app/controllers/events_controller.rb
class EventsController < ApplicationController
   def new
      @event = Event.new
   end

   def create
      @event = Event.new event_params
      @event.save
   end

   private

   def event_params
      params.require(:event).permit(:master_id, ...)
   end
end

#app/views/events/new.html.erb
<%= form_for @event do |f| %>
  <%= f.collection_select :master_id, Master.all, :id, :name %>
  <%= f.submit %>
<% end %>

-

这比您当前的模式要好得多的原因是,每次创建新的event时,您都可以访问master属性:

@event.master.url #-> "url" from master record

答案 1 :(得分:0)

在Rails中,您通常使用模型创建绑定表单输入并将其传递给form_for(或simple_form_for)。

在这种情况下,如果真的需要动态用户可编辑默认,最明显的解决方案是使用Master为新事件播种。

在大多数情况下,默认值应该是开发人员关注的问题,这些问题在Rich Peck建议的模型层上处理。

同样设置默认值只对新记录有意义 - 为什么要在更新时覆盖用户选择?

def new
  @master = Master.last
  @event = Event.new(@master.attributes.except("id", "created_at", "updated_at"))
end
<%= simple_form_for @newevent do |f| %>
  <%= f.input :eventname %>
<% end %>