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如果它尚未確定,只有在創建新評論)。