1

私はレールに本当に慣れていないので、フォーラムモンスターに基づいたシンプルなフォーラムアプリを持っています。現在、Rails 3.0.9 から 3.2.11 への更新に取り組んでいます。この自己負担の問題を修正した後別の問題に遭遇しました。

トピックを表示しようとすると、(post.user からの) ユーザー オブジェクトが nil であってはならないときに nil になっているように見えます。

ここにエラーがあります

Extracted source (around line #17):
14:       <% @topic.posts.each do |post| %>
15:       <tr>
16:         <td class="post_author" rowspan="2">
17:           <span class="name"><%= post.user.username %></span>
18:           <span class="avatar"><%= image_tag post.user.gravatar_url %></span>
19:           <span class="info smaller">
20:             <p><strong><%= "Administrator" if post.user.admin? %></strong></p>

ここに私のビュー app/views/topics/show.html.erb があります

<div class="right controls"><%= link_to "Back to Forum", forum_path(@topic.forum) %></div>
<div class="module">
  <div class="module_header">
    <%= @topic.title %>
    <span class="right controls">
      <%= link_to "Edit", edit_topic_path(@topic) if can? :manage, @topic %>
      <%= link_to "Delete", @topic, :confirm => "Are you sure?", :method => :delete if can? :manage, @topic %>
      <%= link_to @topic.sticky ? "Unstick" : "Sticky", {:controller => 'topics', :action => 'update', :topic => {:sticky => @topic.sticky ? "false" : "true" }}, :method => :put if can? :moderate, @topic %>
      <%= link_to @topic.locked ? "Unlock" : "Lock", {:controller => 'topics', :action => 'update', :topic => {:locked => @topic.locked ? "false" : "true" }}, :method => :put if can? :moderate, @topic %>
    </span>
  </div>
  <div>
    <table>
      <% @topic.posts.each do |post| %>
      <tr>
        <td class="post_author" rowspan="2">
          <span class="name"><%= post.user.username %></span>
          <span class="avatar"><%= image_tag post.user.gravatar_url %></span>
          <span class="info smaller">
            <p><strong><%= "Administrator" if post.user.admin? %></strong></p>
            Posts <%= post.user.posts.size %><br />
            Registered <%=l post.user.created_at %><br />
          </span>
        </td>
        <td class="post_header">
          <span class="left post_date smaller">Posted <%=l post.created_at %></span>
          <span class="right controls">
            <%= link_to "Reply", new_topic_post_path(@topic) if can? :create, @topic.posts.new %>
            <%= link_to "Quote", new_topic_post_path(@topic, :quote => post) if can? :create, @topic.posts.new %>
            <%= link_to "Edit", edit_post_path(post) if can? :update, post %>
            <%= link_to "Delete", post, :confirm => "Are you sure?", :method => :delete if can? :destroy, post %>
          </span>
        </td>
      </tr>
      <tr>
        <td class="post_body">
          <%= post.body.bbcode_to_html().html_safe %>
        </td>
      </tr>
      <% end %>
    </table>
  </div>
</div>
<div class="right controls"><p><%= link_to "Back to Forum", forum_path(@topic.forum) %></p></div>

ここにコントローラー app/controlers/topics_controller.rb があります

class TopicsController < ApplicationController
  load_and_authorize_resource :forum
  load_and_authorize_resource :topic, :through => :forum, :shallow => true

  def show
    @topic.hit! if @topic
  end

  def create
    @topic.user ||= current_user

    if @topic.save
      flash[:notice] = "Topic was successfully created."
      redirect_to topic_url(@topic)
    else
      render :action => 'new'
    end
  end

  def update
    if @topic.update_attributes(params[:topic])
      flash[:notice] = "Topic was updated successfully."
      redirect_to topic_url(@topic)
    end
  end

  def destroy
    if @topic.destroy
      flash[:notice] = "Topic was deleted successfully."
      redirect_to forum_url(@topic.forum)
    end
  end

end

Rails コンソール出力は、ビュー内のコードが機能すること、および投稿にユーザーが含まれていることを確認します。

ricky ~/forum $ rails c
Loading development environment (Rails 3.2.11)
irb(main):001:0> Topic.find(1).posts.each do |p|
irb(main):002:1* puts p.user.username
irb(main):003:1> end
  Topic Load (0.5ms)  SELECT `topics`.* FROM `topics` WHERE `topics`.`id` = 1 ORDER BY sticky DESC, updated_at DESC LIMIT 1
  Post Load (0.4ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`topic_id` = 1 ORDER BY created_at ASC
  User Load (0.5ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
admin
=> [#<Post id: 1, body: "Forum Monster is a simple forum generator written i...", forum_id: 1, topic_id: 1, user_id: 1, created_at: "2013-01-19 06:57:23", updated_at: "2013-01-19 06:57:23">]
irb(main):004:0>

cancan can :read User の機能を追加する必要があるかもしれないと思いますが、よくわかりません。

この混乱した Android 開発者を助けてくれてありがとう 0.o

編集

ここで完全なソースを表示

以下に示すように、投稿モデルは実際にユーザーの存在を検証します

アプリ/モデル/post.rb

class Post < ActiveRecord::Base

  # Associations
  belongs_to :forum, :counter_cache => true
  belongs_to :topic, :counter_cache => true, :touch => true 
  belongs_to :user, :class_name => "User", :counter_cache => true

  # Accessors
  attr_accessible :body

  # Validations
  validates :body, :presence => true
  validates :user, :presence => true

  # Default Scope
  default_scope :order => 'created_at ASC'

  # Scope to display only the last n posts. Used for "Recent Posts" display
  scope :recent, lambda {
    |c| reorder('created_at desc').limit(c)
  }

  # Callbacks
  before_save :topic_locked?

  # Methods
  private
    def topic_locked?
      if topic.locked?
        errors.add(:base, "That topic is locked")
        false
      end
    end
end

シードされたデータベースに存在する投稿が1つしかなく、それが作成されたことがわかりました

@current_user = User.find_by_username("admin")
@current_user.topics.create!(...)
4

4 に答える 4

2

データベースには投稿が1つしかないため、これで問題が解決した理由がよくわかりません。しかし、私は解決策を見つけました。

<% @topic.posts.each do |post| %>
  <% if !post.user.blank? %>
    ...display post here...
  <%end%>
<%end%>
于 2013-01-20T16:01:40.277 に答える
2

と置換する:

<%= post.user.username unless post.user.blank? %>
于 2013-01-19T08:21:21.697 に答える
0

ビューでは、コレクション@topic.postsにユーザーのいない投稿が少なくとも1つ含まれており、ビューの残りのコードはそれを予期していません。

  • おそらく、アプリケーションはユーザーなしで投稿を作成することを許可するべきではありません。投稿が保存されるときにユーザーが存在することを確認する検証を追加し、ユーザーなしで投稿が作成されないようにする必要があります。

    validates :user_id, :presence => true
    
  • アプリケーションでユーザーなしの投稿を許可する必要がある場合if post.user.present?は、ビューにを追加します。

    <% @topic.posts.each do |post| %>
      <tr>
        <td class="post_author" rowspan="2">
          <% if post.user.present? %>
            <span class="name"><%= post.user.username %></span>
            <span class="avatar"><%= image_tag post.user.gravatar_url %></span>
            <span class="info smaller">
              <p><strong><%= "Administrator" if post.user.admin? %></strong></p>
              Posts <%= post.user.posts.size %><br />
              Registered <%=l post.user.created_at %><br />
            </span>
          <% end %>
        </td>
        ... 
    
于 2013-01-19T08:48:24.197 に答える
0

投稿ユーザーを常に空白にするか、まったく空白にしないかによって、2 つの方法があります。

1) 投稿ユーザーを空白にできる場合:

投稿ユーザーが存在するかどうかを確認してください。これにより、「nil」ユーザーは取得されません。

'@userpost = post.user.blank? " ": post.user.username'

2) 投稿ユーザーを空白にできない場合:

この場合、post モデルでは「belongs_to :user」、ユーザー モデルでは「has_many :posts」のような関連付けと、「validates_presence_of :post」のような制約を課すことができます。

于 2013-01-19T10:12:41.717 に答える