【问题标题】:How to create a parent model through a child controller in rails 3? (belongs_to association)如何通过rails 3中的子控制器创建父模型? (belongs_to 协会)
【发布时间】:2011-05-01 03:36:13
【问题描述】:

我有两个资源:主题和帖子。 我试图弄清楚如何通过 Post 控制器创建主题。 模型如下所示:

class Topic < ActiveRecord::Base
  has_many :posts, :dependent => :destroy
  validates :name, :presence => true,
                   :length => { :maximum => 32 }
  attr_accessible  :name
end

class Post < ActiveRecord::Base
  belongs_to :topic,    :touch => true
  has_many   :comments, :dependent => :destroy
  accepts_nested_attributes_for :topic
  attr_accessible :name, :title, :content, :topic
end

posts/_form.html.erb:

<%= simple_form_for @post do |f| %>
  <h1>Create a Post</h1>
  <%= f.input :name, :label => false, :placeholder => "Name" %>
  <%= f.input :title, :label => false, :placeholder => "Title" %>
  <%= f.input :content, :label => false, :placeholder => "Content" %>
  <%= f.input :topic, :label => false, :placeholder => "Topic" %>  
  <%= f.button :submit, "Post" %>  
<% end %>

posts_controller.rb#create:

def create
  @post = Post.new(params[:topic])
  respond_to do |format|
    if @post.save
      format.html { redirect_to(@post, :notice => 'Post was successfully created.') }
    else
      format.html { render :action => "new" }
    end
  end
end

使用 posts/_form.html.erb 我可以创建帖子,但不会随之创建相关主题。谁能告诉我为什么会出现这种行为以及如何纠正它?我正在使用 Ruby 1.9.2、Rails 3.0.7 和 simple_form gem。

【问题讨论】:

    标签: ruby-on-rails ruby controller associations simple-form


    【解决方案1】:

    Railscasts 有几集关于这个问题。 第 16 集(需要订阅)

    源代码: https://github.com/railscasts/016-virtual-attributes-revised

    还有这一集 http://railscasts.com/episodes/57-create-model-through-text-field

    视图/产品/_form.rhtml

    <p>
    <label for="product_category_id">Category:</label><br />
    <%= f.collection_select :category_id, Category.find(:all), :id, :name, :prompt => "Select a Category" %>
    or create one:
    <%= f.text_field :new_category_name %>
    </p>
    

    models/product.rb

    belongs_to :category
    attr_accessor :new_category_name
    before_save :create_category_from_name
    
    def create_category_from_name
    create_category(:name => new_category_name) unless new_category_name.blank?
    end
    

    我认为 Ryan 的类别解决方案比 @nathanvda 的选项 1 更优雅。因为它在模型而不是控制器中处理数据。如果你需要在不同的控制器/动作中做同样的工作,你会看到好处。

    【讨论】:

      【解决方案2】:

      根据您想要做什么,我可以看到两个选项。

      选项 1:使用文本框创建或查找现有主题(如您所见)。在您的控制器中,您可以编写如下内容:

      def create
        topic_name = params[:post].delete(:topic)
        @topic = Topic.find_or_create_by_name(topic_name)
        @post = Post.new(params[:post])
        @post.topic = @topic
        if @post.save
          format.html { redirect_to(@post, :notice => 'Post was successfully created.') }
        else
          format.html { render :action => "new" }
        end
      end
      

      这是一种快速而肮脏的方式。对于您键入的每个topic,它将尝试按名称查找该主题,或者创建它并分配它。但是,这很容易出错。如果您的主题集有限,还有一种更简单的方法。

      选项 2:使用选择框,即可用主题列表。在你看来写:

      <%= simple_form_for @post do |f| %>
        <h1>Create a Post</h1>
        <%= f.input :name, :label => false, :placeholder => "Name" %>
        <%= f.input :title, :label => false, :placeholder => "Title" %>
        <%= f.input :content, :label => false, :placeholder => "Content" %>
        <%= f.association :topic %>  
        <%= f.button :submit, "Post" %>  
      <% end %>
      

      这将呈现一个带有可能主题的选择框。在你的控制器中你只需要写:

      def create
        @post = Post.new(params[:post])
        if @post.save
          format.html { redirect_to(@post, :notice => 'Post was successfully created.') }
        else
          format.html { render :action => "new" }
        end
      end
      

      虽然第二个选项非常简单,但动态添加主题却不太容易。您可以在两者之间做一些事情,使用自动完成字段,这将允许查找值(如果存在),或者添加新值(如果它们不存在)。

      希望这会有所帮助。

      【讨论】:

      • 这成功了!我正计划为该字段实现自动完成,并且知道选择框方法。非常感谢您的宝贵时间。
      【解决方案3】:

      您是否在服务器日志中收到批量分配错误?您可能需要将 :topic_attributes 添加到您的 attr_accessible 列表中。

      【讨论】:

      • 我收到了批量分配错误,由于您的建议,我不再收到它。主题仍未创建:(
      • 我对 simple_form 一无所知,但是对于常规的嵌套表单,您的视图中会出现类似 f.fields_for :topic do |topic| 的内容。看看关于nested_form 的railscast:asciicasts.com/episodes/196-nested-model-form-part-1
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-08
      • 2013-01-09
      • 1970-01-01
      • 2013-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多