【问题标题】:no route matches leading to ActionController UrlGenerationError没有路由匹配导致 ActionController UrlGenerationError
【发布时间】:2019-01-21 02:58:46
【问题描述】:

我根据 Hartl 的教程创建了一个 ToDoList,并按照 videoworded tutorial 添加标记系统。我一直关注到第 10 节,他们要求我将我的 new.html.erb 文件修改为源代码中显示的代码。为了即兴解决代码的结构差异,我会编辑一些其他文件,比如在这种情况下,我的 micropost_form partial 代替。有时,我会在视频中的代码和文字教程中的代码之间交替使用,因为其中一些会产生错误消息或不会产生所需的功能。以下是我认为与此问题有关的文件。

_micropost_form.html.erb(用户主页上显示的填写表格)

<%= simple_form_for @micropost do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">
    <%= f.label :content %><br />
    <%= f.text_area :content, placeholder: "Add new task..." %>
  </div>
  <div class="field">
    <%= f.label :tag_list, "Tags (separated by commas)" %><br />
    <%= f.text_field :tag_list %> 
  </div>
  <%= f.submit "Add Task", class: "btn btn-primary" %>
<% end %>

micropost.html.erb(用于显示单个微帖子)

<li id="micropost-<%= micropost.id %>">
  <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
  <span class="user"><%= link_to micropost.user.name, user_path(micropost.user) %></span>
  <span class="content"><%= micropost.content %></span>
  <p><small>Tags: <%= raw micropost.tags.map(&:name).map { |t| link_to t, tag_path(t) }.join(', ') %></small</p>
  <span class="timestamp">
    Posted <%= time_ago_in_words(micropost.created_at) %> ago.
    <% if current_user?(micropost.user) %>
      <%= link_to "Done", micropost_path(micropost), method: :delete, data: { confirm: "Keep up the good work!" } %>
    <% end %>
  </span>
</li>

routes.rb

Rails.application.routes.draw do
  resources :users
  resources :microposts          

  get    '/about',   to: 'static_pages#about'
  get    '/contact', to: 'static_pages#contact'
  get    '/signup',  to: 'users#new'
  post    '/signup',  to: 'users#create'
  get    '/login',    to: 'sessions#new'
  post   '/login',    to: 'sessions#create'
  delete '/logout',   to: 'sessions#destroy'
  get   '/users/admin',     to: 'users#admin'

  get 'tags/:tag', to: 'microposts#index', as: :tag

  root   'static_pages#home'
end

micropost_controller

class MicropostsController < ApplicationController
  before_action :logged_in_user, only: [:create, :destroy]
  before_action :correct_user,   only: :destroy


  def index
    params[:tag] ? @microposts = Micropost.tagged_with(params[:tag]) : @microposts = Micropost.all
  end


  def show
    @micropost = Micropost.find(params[:id])
  end

  def create
    @micropost = current_user.microposts.build(micropost_params)
    if @micropost.save
      flash[:success] = "Micropost created!"
      redirect_to root_url
    else
      @feed_items = []
      render 'static_pages/home'
    end
  end

  def destroy
    @micropost.destroy
    flash[:success] = "You have deleted a task!"
    redirect_to request.referrer || root_url
  end

  private

    def micropost_params
      params.require(:micropost).permit(:content, :tag_list, :tag, 
        {tag_ids: [] }, :tag_ids)
    end

    def correct_user
      @micropost = current_user.microposts.find_by(id: params[:id])
      redirect_to root_url if @micropost.nil?
    end
end

微博模型

class Micropost < ApplicationRecord
  belongs_to :user
  has_many :taggings
  has_many :tags, through: :taggings
  default_scope -> { order(created_at: :desc) }
  validates :user_id, presence: true
  validates :content, presence: true, length: {maximum: 140 }
  attr_accessor :tag_list



  def self.tagged_with(name)
    Tag.find_by!(name: name).microposts
  end

  def self.tag_counts
    Tag.select('tags.*, count(taggings.tag_id) as count')
    .joins(:taggings).group('taggings.tag_id')
  end

  def tag_list
    tags.map(&:name).join(', ')
  end

  def tag_list=(names)
    self.tags = names.split(',').map do |n|
      Tag.where(name: n.strip).first_or_create!
    end
  end
end

标签模型

class Tag < ApplicationRecord
    attr_accessor :name
  has_many :taggings
  has_many :microposts, through: :taggings
end

static_pages 控制器

class StaticPagesController < ApplicationController
  def home
    if logged_in?
      @micropost  = current_user.microposts.build
      @feed_items = current_user.feed.paginate(page: params[:page])
    end
  end

  def help
  end

  def about
  end

  def contact
  end
end

feed.html.erb

<% if @feed_items.any? %>
  <ol class="microposts">
    <%= render @feed_items %>
  </ol>
  <%= will_paginate @feed_items %>
<% end %>

我收到以下错误

ActionController::UrlGenerationError in StaticPages#home
No route matches {:action=>"index", :controller=>"microposts", :tag=>nil}, missing required keys: [:tag]

app/views/microposts/_micropost.html.erb:5:in `block in _app_views_microposts__micropost_html_erb___3891111682689684005_70324923859580'
app/views/microposts/_micropost.html.erb:5:in `map'
app/views/microposts/_micropost.html.erb:5:in `_app_views_microposts__micropost_html_erb___3891111682689684005_70324923859580'
app/views/shared/_feed.html.erb:3:in `_app_views_shared__feed_html_erb__3168328449514417483_70324923896060'
app/views/static_pages/home.html.erb:13:in `_app_views_static_pages_home_html_erb__3511776991923566869_70324898321240'

谁能建议这里可能有什么问题?如果需要更多信息,请告诉我。

更新:我已经实现了下面答案提供的一些更改,但仍然不明白为什么没有检测到:tag,以及为什么红色的代码实际上是突出显示的。

【问题讨论】:

  • 什么时候出现错误?重定向时在表单提交或控制器内部?使用pry gem 进行调试并注意您的操作正在尝试使用缺少tag_id 的Micropost#index。我猜路线不合适
  • 当我运行rails server 并到达0.0.0.0:3000 时出现错误。当我尝试访问index 时,我看不到tag_id 是如何被使用的,对不起,rails 新手
  • :) 错误在您的routes.rb 中。确保生成错误的完整日志
  • 完整日志是什么意思?我知道它来自routes.rb,但不知道为什么不使用:tag

标签: ruby-on-rails ruby routes


【解决方案1】:
ActionController::UrlGenerationError in StaticPages#home
No route matches {:action=>"index", :controller=>"microposts", :tag=>nil}, missing required keys: [:tag]

问题是你的微博没有索引路由。

Rails.application.routes.draw do
  root   'static_pages#home'
  get    '/readme',    to: 'static_pages#readme'
  get    '/about',   to: 'static_pages#about'
  get    '/contact', to: 'static_pages#contact'
  get    '/signup',  to: 'users#new'
  post    '/signup',  to: 'users#create'
  get    '/login',    to: 'sessions#new'
  post   '/login',    to: 'sessions#create'
  delete '/logout',   to: 'sessions#destroy'
  get   '/users/admin',     to: 'users#admin'
  resources :users
  resources :microposts,          only: [:create, :destroy] #Here's the problem
  get 'tags/:tag', to: 'microposts#index', as: :tag
end

改为:

resources :microposts, only: [:index, :create, :destroy]

编辑:

另一个问题是

if logged_in?
  @micropost  = current_user.microposts.build #this just returns a new 1
  @feed_items = current_user.feed.paginate(page: params[:page])
end

你可能想要这样的东西:

if logged_in?
  @microposts  = current_user.microposts
  @feed_items = Micropost.all.paginate(page: params[:page])
end

这将为您提供所有用户的微博。然后在视图中遍历它们。

【讨论】:

  • 嗨 Helsing,感谢您的回答,但更改并没有更改我的错误消息,但感谢您提醒我更新代码
  • 我明白了。好像标签有问题。如果还没有解决,我今天晚些时候再看看。
  • 非常感谢您提前提供的帮助。
  • @micropost = current_user.microposts.build 为您提供了一个没有任何标签的新微博,这可能就是您看到它的原因。可能存在多个问题,因此一旦您清除其中一个,就会遇到另一个错误。
  • 感谢您的建议,我确实遇到了undefined method to_key for #&lt;Micropost::ActiveRecord_Associations_CollectionProxy:0x00007fd2668ec4d0 的另一个错误,将在另一个问题中发布,链接回此帖子
【解决方案2】:

我实际上发现问题的原因很简单。运行rails console 后,似乎我的 db:seed 甚至没有正确耙过,导致我的标签有nil 名称并导致我无法找到路线。进一步查看Rails console is adding nil instead of values 以解决我的种子添加问题,我意识到我已经添加了attr_accessor,忘记了应该通过命令行将普通属性添加到迁移中,而不是直接写入模型中。根据帖子删除它会更新我的数据库并且代码有效。

【讨论】:

    猜你喜欢
    • 2015-11-26
    • 1970-01-01
    • 2019-05-25
    • 1970-01-01
    • 2016-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多