4


我想创建包含另一个模型在轨道中的窗体。我已经完成了这与使用accep_nested_attibutes和它工作得很好。问题是我在该表中有一个额外的字段,记录每条评论的用户名,我不确定如何在创建新评论时插入该信息。应用程序控制器使用“current_user”方法提供用户名。Rails 3 - 嵌套窗体和默认值

问候,
凯尔

评论模型

class Comment < ActiveRecord::Base 
    belongs_to :post 
    before_save :set_username 

    private 
    def set_username 
     self.created_by = current_user 
    end 
    end 

应用控制器(这仅仅是一个沙盒应用程序,所以我只是把一个字符串中的方法)

class ApplicationController < ActionController::Base 
    protect_from_forgery 
    helper_method :current_user 

    def current_user 
    "FName LName" 
    end 

end 

显示视图

<p id="notice"><%= notice %></p> 
<p> 
    <b>Title:</b> 
    <%= @post.title %> 
</p> 
<div id="show_comments"><%= render 'comments' %></div> 
<div id="add_comments"> 
    Add Comment 
    <%= form_for @post, :url => {:action => 'update', :id => @post.id}, :html => { :'data-type' => 'html', :id => 'create_comment_form' } do |f| %> 
     <%= f.fields_for :comments, @new_comment do |comment_fields| %> 
      <%= comment_fields.text_area :content %> 
     <%end%> 
     <div class="validation-error"></div> 
     <%= f.submit %> 
    <% end %> 
</div> 

柱控制器

def update 
    @post = Post.find(params[:id]) 
    respond_to do |format| 
     if @post.update_attributes(params[:post]) 
     @comments = @post.comments.all 
     format.html { redirect_to({:action => :show, :id => @post.id}, :notice => 'Post was successfully created.') } 
     format.xml { render :xml => @post, :status => :created, :location => @post } 
     else 
     format.html { render :action => "new" } 
     format.xml { render :xml => @post.errors, :status => :unprocessable_entity } 
     end 
    end 
    end 
+0

你看过吗:http://railscasts.com/episodes/197-nested-model-form-part-2? – apneadiving 2011-04-08 19:34:18

+0

我做了,我无法找到任何可以帮助我的地方。 – Kyle 2011-04-08 20:38:31

+0

你应该提供你的意见表格代码 – apneadiving 2011-04-08 20:42:09

回答

4

我本来想,你可以只将其设置为默认或在模型中before_save。但型号无法访问current_user。所以最好在控制器中设置当前用户。它并不像DRY那样处于模型中,但它不那么笨拙并且可能存在问题。

def update 
    @post = Post.find(params[:id]) 
    @post.attributes = params[:post] 
    @post.comments.each do |comment| 
    comment.created_by = current_user if comment.new_record? 
    end 
    respond_to do |format| 
    if @post.save 
     @comments = @post.comments.all 
     format.html { redirect_to({:action => :show, :id => @post.id}, :notice => 'Post was successfully created.') } 
     format.xml { render :xml => @post, :status => :created, :location => @post } 
    else 
     format.html { render :action => "new" } 
     format.xml { render :xml => @post.errors, :status => :unprocessable_entity } 
    end 
    end 
end 
+0

有点矫枉过正,但值得注意,+1 :) – apneadiving 2011-04-08 20:00:27

+0

我宁愿它被迫。 – Kyle 2011-04-08 20:39:41

+0

当我尝试一个我得到“未定义的局部变量或方法'current_user'为#”。它看起来像无法从应用程序控制器访问方法。 – Kyle 2011-04-08 20:41:25

0

只是想指出可以在模型范围内访问current_user。在这种情况下,我不认为这是必要的,因为来自@aNble的解决方案应该可行。所以如果可以从控制器设置current_user,我宁愿这样做。

总之,我们添加一个方法到User

class User < ActiveRecord::Base 
    cattr_accessor :current_user 

    def self.current_user 
    @current_user ||= User.new("dummy-user") 
    end 
    ... 
end 

,并在您的应用程序controllor,我们添加一个before_filter设置它。确保在完成身份验证后调用此筛选器。

class ApplicationController < ActionController::Base 

    before_filter { |c| User.current_user = current_user } 

end 

而且,那里面你Comment -model你可能只是做类似

class Comment 

    before_create :set_user 

    def set_user 
    created_by = User.current_user unless created_by 
    end 
end 

(所以我只设置created_by如果它尚未确定,只有在创建新评论)。