在Rails 4

时间:2015-07-30 00:18:16

标签: ruby-on-rails ruby ruby-on-rails-4

所以我正在建立一个论坛,一切都设置/运行良好,除了我的回复没有出现在线程“show”页面上。检查rails控制台后,我看到它们正在保存,但user_id和discussion_id都没有。 user_id总是为nil,discussion_id总是为0.讨论线程更容易设置但是有了这些回复,我显然似乎遇到了问题。以下是我的代码片段:

class PostsController
  # ...

  before_filter :authenticate_user!
  before_filter :set_discussion, only: [:new, :create, :destroy]

  def create
    @post = @discussion.post.new(create_params) do |post|
      post.user = current_user
    end  
    if @post.save
      redirect_to @discussion, notice: "It has been posted!" 
    else
      render :new
    end
  end

  def destroy
    @post = @discussion.posts.find(params[:id])
    @post.destroy
    flash.notice = "Deleted"
    redirect_to discussion_path(@discussion)
  end

  private

  def create_params
    params.require(:post).permit(:reply)
  end

  def set_discussion
    @discussion = Discussion.friendly.find(params[:id])
  end
end
class DiscussionsController
  def show
    @discussion = Discussion.friendly.find(params[:id])
    @post = Post.new
    render :layout => 'discussion'
  end
end

部分呈现回复:

<h2>Reply</h2>

<%= form_for [ @discussion, @post ] do |f| %>
  <p>
    <%= f.label :reply, "Reply" %><br/>
    <%= f.text_field :reply %>
  </p>
    <p>
    <%= f.submit 'Submit' %>
  </p>
<% end %>

部分呈现以在讨论页面上显示回复:

<h3><%= post.user.first_name %></h3>
<%= post.reply %>
Posted: <%= post.created_at.strftime("%b. %d %Y") %></p>
<p><%= link_to "Delete Comment", [post.discussion, post], data: {confirm: "Are you sure you wish to delete?"}, method: :delete, :class => "post_choices" %></p>

只是想提一下,我在三个模型(用户,讨论,帖子)之间也有正确的关联。如果需要更多代码,请告诉我。我非常感谢任何可能有用的信息=)

修改

class User < ActiveRecord::Base
  has_many :articles
  has_many :discussions
  has_many :posts

  # ...
end

class Discussion
  belongs_to :user
  has_many :posts
  extend FriendlyId
  friendly_id :subject, use: :slugged
end

class Post
  belongs_to :discussion
  belongs_to :user
end

如果需要,我可以发布整个用户模型但是它的所有验证/设计方面= P其他两个我列出了模型中的所有内容。

修改2

感谢Max,user_id在控制台中正确返回,但仍未进行讨论。用最近的变化去挖掘一下,看看还有什么=)

1 个答案:

答案 0 :(得分:1)

您需要处理一些问题。

首先,您应确保Devise实际上正在授权您的控制器操作。

class PostsController < ApplicationController
  before_filter :authenticate_user!
end

如果没有已登录的用户,则current_user将返回nil。我是 猜测你不希望未经过身份验证的用户能够创建帖子。

此外,如果你有一个嵌套路线,你很可能想要检查实际的讨论 在尝试添加帖子之前存在。

class PostsController
  before_filter :authenticate_user!
  before_filter :set_discussion, only: [:new, :create, :destroy]

  private

  # Will raise an ActiveRecord::NotFoundError
  # if the Discussion does not exist
  def set_discussion
    @discussion = Discussion.friendly.find(params[:id])
  end
end

在创建资源时,请注意不要不必要地查询数据库。 这尤其适用于昂贵的CREATEUPDATE查询。

def create
  @post = Post.create(post_params) # INSERT INTO 'users'
  @post.discussion_id = params[:discussion_id]
  @post.user = current_user
  @post.save # UPDATE 'users'
  flash.notice = "It has been posted!"
  redirect_to discussions_path(@post.discussion)
end

此外,您甚至无法检查记录是否已成功创建。

所以我们把它们放在一起:

class PostsController
  before_filter :authenticate_user!
  before_filter :set_discussion, only: [:new, :create, :destroy]

  def new
    @post = @discussion.post.new
  end

  def create
    # new does not insert the record into the database
    @post = @discussion.post.new(create_params) do |post|
      post.user = current_user
    end  
    if @post.save
      redirect_to @discussion, notice: "It has been posted!" 
    else
      render :new # or redirect back
    end
  end

  def destroy
    @post = @discussion.posts.find(params[:id])
    @post.destroy
    flash.notice = "Deleted"
    redirect_to discussion_path(@discussion)
  end

  private    

  def create_params
    # Only permit the params which the user should actually send!
    params.require(:post).permit(:reply)
  end

  # Will raise an ActiveRecord::NotFoundError
  # if the Discussion does not exist
  def set_discussion
    @discussion = Discussion.friendly.find(params[:id])
  end
end