Rails 3 - 嵌套表单和默认值

发布于 2024-10-31 15:39:30 字数 2044 浏览 4 评论 0原文


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

问候,
Kyle

评论模型

    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

I am trying to create form that contains another model in rails. I have accomplished this with using accepts_nested_attibutes and it is working great. The problem is I have an additional field in that table that records the User Name for each comment and I am not sure on how to insert that information when a new comment is being created. The username is being supplied by the Application Controller using the "current_user" method.

Regards,
Kyle

Comment Model

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

    private
     def set_username
      self.created_by = current_user
     end
    end

Application Controller (This is just a Sandbox app so I just put a string in the method)

class ApplicationController < ActionController::Base
  protect_from_forgery
  helper_method :current_user

  def current_user
    "FName LName"
  end

end

Show View

<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>

Post Controller

  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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

抱猫软卧 2024-11-07 15:39:30

我最初认为您可以将其设置为默认值或模型中的 before_save 。但模型无权访问 current_user。因此,最好只在控制器中设置当前用户。它并不像将其放入模型中那么干燥,但这种方式不那么老套且可能存在问题。

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

I was originally thinking you could just set it as a default or a before_save in the model. But models don't have access to current_user. So it's probably best to just set the current user in the controller. It's not as DRY as putting it in the model but it's less hackey and potentially problematic this way.

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
深海里的那抹蓝 2024-11-07 15:39:30

只是想指出,可以在模型范围内访问 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 模型中,您可以执行类似的操作

class Comment

  before_create :set_user

  def set_user
    created_by = User.current_user unless created_by
  end
end

(因此我仅在尚未设置时设置 created_by ,并且仅在创建新评论时设置)。

Just want to point out that it is possible to access current_user in the model scope. In this case I don think it is necessary, as the solution from @aNoble should work. So if is possible to set the current_user from the controller, I would prefer that.

In short, we add a method to the User class

class User < ActiveRecord::Base
  cattr_accessor :current_user

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

and in your application controllor, we add a before_filter that sets it. Make sure to call this filter after your authentication is done.

class ApplicationController < ActionController::Base

  before_filter { |c| User.current_user = current_user }

end

And, then inside your Comment-model you could just do something like

class Comment

  before_create :set_user

  def set_user
    created_by = User.current_user unless created_by
  end
end

(so I only set the created_by if it was not yet set, and only upon creation of a new comment).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文