从一个控制器/视图将数据插入多个表[Rails 4]

时间:2013-10-18 22:02:44

标签: ruby-on-rails ruby forum

对于所有令人惊叹的人,我有更多好奇的问题!

我正在创建一个论坛,当您创建主题时,您也在同时创建第一篇文章。

我需要为某些字段分配变量。

示例:: user_id => current_user.id,

我没有正确的参数设置,所以当存储在数据库中时,许多字段都是NULL。

模型

class Topic < ActiveRecord::Base
  belongs_to :forum
  has_many :posts, :dependent => :destroy  
  belongs_to :user
  accepts_nested_attributes_for :posts
end

class Post < ActiveRecord::Base  
  belongs_to :topic  
  belongs_to :user
end

主题控制器

# GET /topics/new
def new
  @topic = Topic.new
  @topic.posts.build
end

def create  
  @topic = Topic.new(topic_params)

  if @topic.save 
    #@topic.responses = Post.new(params[:responses])
    flash[:success] = "Topic Posted"
    redirect_to "/forums/#{@topic.forum_id}" 
  else  
    render :new  
  end   
end

def topic_params
  # last_post_at = (:last_post_at => Time.now)
  params.require(:topic).permit(
    :name, 
    :description, 
    [:last_poster_id => current_user.id], 
    [:last_post_at => Time.now], 
    [:user_id => current_user.id],
    :forum_id,
    posts_attributes: [:id, :content, :topic_id, :user_id => current.user.id] )
end

后置控制器

# GET /posts/new
def new
  @post = Post.new
end

def create  
  @post = Post.new(
    :content => params[:post][:content], 
    :topic_id => params[:post][:topic_id], 
    :user_id => current_user.id)  

  if @post.save  
    @topic = Topic.find(@post.topic_id)  
    @topic.update_attributes(
      :last_poster_id => current_user.id, 
      :last_post_at => Time.now)  
    flash[:notice] = "Successfully created post."  
    redirect_to "/topics/#{@post.topic_id}"  
  else  
    render :action => 'new'  
  end  
end  

_form for View / Topic

<%= form_for(@topic) do |f| %>
  <% if params[:forum] %>
    <input type="hidden" 
    id="topic_forum_id" 
    name="topic[forum_id]" 
    value="<%= params[:forum] %>" />
  <% end %>  

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

  <%= f.fields_for :posts do |p| %>

    <%= p.label :content %><br />
    <%= p.text_area :content %>

  <% end %>
  <%= f.submit :class => "btn btn-primary" %>
<% end %>

3 个答案:

答案 0 :(得分:2)

您可能正在寻找一个名为:

的功能
accepts_nested_attributes_for

你把它放到你正在使用的模型中(在你的情况下是Post),它会将嵌套模型的paeans传递给相应的控制器

有一个很好的RailsCast about this,我也有一些经验。如果您希望我发布实时代码,请告诉我(我在我的iPhone上)


直播代码

模型

#app/models/image_post.rb
belongs_to :post, :class_name => 'Post'
belongs_to :image, :class_name => 'Image'
accepts_nested_attributes_for :image, :allow_destroy => true

#app/models/post.rb
has_many :images, -> { uniq }, :class_name => 'Image', :through => :images_posts, dependent: :destroy
has_many :images_posts, :class_name => 'ImagePost'
accepts_nested_attributes_for :images_posts, :allow_destroy => true

控制器

    def new
            @post = Post.new
            @post.images_posts.build.build_image
    end

    def create
            #Using Inherited Resources Gem
            create! 
    end

    private
    def permitted_params
            {:post => params.require(:post).permit(:title, :body, images_posts_attributes: [:caption, image_attributes: [:image]] )}
    end

表格

<%= form_for [:admin, resource], :html => { :multipart => true }  do |f| %>
        <table class="resource_table">
                <thead>
                        <th colspan="2"><%= params[:action].capitalize %> <%= resource_class %></th>
                </thead>
                <tbody class="form">
                        <% attributes.each do |attr| %>
                                <tr class="<%= cycle('odd', '')%>">
                                        <td><%= resource_class.human_attribute_name(attr) %></td>
                                        <td>
                                                <% if attr == "body" %>
                                                        <%= f.text_area attr, :rows => 60, :cols => 80, :class => "redactor" %>
                                                <% else %>
                                                        <%= f.text_field attr, :value => resource.public_send(attr).to_s %>
                                                <% end %>
                                        </td>
                                </tr>
                        <% end %>
                        <%= f.fields_for :images_posts do |images_posts| %>
                                <%= images_posts.fields_for :image do |images| %>
                                        <tr>
                                                <td>Image</td>
                                                <td><%= images.file_field :image %></td>
                                        </tr>
                                <% end %>
                                <tr>
                                        <td>Caption</td>
                                        <td><%= images_posts.text_field :caption %></td>
                                </tr>
                        <% end %>
                        <tr class="dull">
                                <td colspan="2"><%= f.submit "Go" %></td>
                        </tr>
                </tbody>
        </table>
<% end %>

答案 1 :(得分:0)

使用accepts_nested_attributes

class topic
 accepts_nested_attributes :posts
end

class post
  accepts_nested_attributes :topic
end

然后在表单中,您可以在创建主题表单时使用fields_for帖子 同样在帖子形式fileds_for主题

答案 2 :(得分:0)

您可能希望将fetch邮政参数作为

params[:topic].fetch(:post_attributes, nil)

Rails 4已经对大规模分配进行了清理,称为strong_params Example