【问题标题】:Rails 3 - Nested Forms and Default ValuesRails 3 - 嵌套表单和默认值
【发布时间】:2011-04-08 19:29:34
【问题描述】:


我正在尝试创建包含 Rails 中另一个模型的表单。我已经通过使用 accept_nested_attibutes 实现了这一点,并且效果很好。问题是我在该表中有一个额外的字段记录每个评论的用户名,我不确定在创建新评论时如何插入该信息。用户名由应用程序控制器使用“current_user”方法提供。

问候,
凯尔

评论模型

    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

【问题讨论】:

标签: ruby-on-rails ruby-on-rails-3 default-value nested-attributes


【解决方案1】:

我最初认为您可以将其设置为模型中的默认值或 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

【讨论】:

  • 有点矫枉过正但值得注意,+1 :)
  • 当我尝试那个时,我得到“#<0x104ee4cb0>
【解决方案2】:

只想指出可以在模型范围内访问current_user。在这种情况下,我认为这是必要的,因为@aNoble 的解决方案应该可以工作。因此,如果可以从控制器设置 current_user,我会更喜欢。

简而言之,我们在User 类中添加一个方法

class User < ActiveRecord::Base
  cattr_accessor :current_user

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

在您的应用程序控制器中,我们添加一个设置它的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 如果尚未设置,并且仅在创建新评论时设置)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多