【问题标题】:Rails Error - params not passing user id from controllerRails 错误 - 参数未从控制器传递用户 ID
【发布时间】:2016-08-06 10:49:40
【问题描述】:

我正在构建一个活动应用程序,我正在尝试创建一个从活动显示页面到活动创建者个人资料的链接,但我收到以下错误 -

ActiveRecord::RecordNotFound in UsersController#show 找不到 'id'=21 的用户

错误突出显示用户控制器中的这一特定代码行 -

def show
    @user = User.find(params[:id])

end

开发日志产生这个输出 -

于 2016 年 4 月 15 日 12:37:08 +0100 开始为 ::1 获取“/users/21” 由 UsersController#show 处理为 HTML 参数:{"id"=>"21"} [1m[36mUser Load (0.1ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1[0m [["id", 8]] [1m[35mUser Load (0.2ms)[0m SELECT "users".* FROM "users" WHERE "users"."id" = ?限制 1 [["id", 21]] Completed 404 Not Found in 14ms (ActiveRecord: 0.9ms)

ActiveRecord::RecordNotFound(找不到 'id'=21 的用户): app/controllers/users_controller.rb:14:in `show'

没有传递用户 ID(在本例中为 5)。我在 show.html.erb 页面中尝试了许多参数,但没有一个可以工作。将 users 控制器中的 show 参数更改为 @user = current_user 只会成功调出查看事件的用户的个人资料,而不是事件创建者的个人资料。

这是我的代码 -

事件控制器

class EventsController < ApplicationController
before_action :find_event, only: [:show, :edit, :update, :destroy,]
# the before_actions will take care of finding the correct event for us
# this ties in with the private method below
before_action :authenticate_user!, except: [:index, :show]
# this ensures only users who are signed in can alter an event

def index
    if params[:category].blank?
        @events = Event.all.order("created_at DESC")
    else
        @category_id = Category.find_by(name: params[:category]).id
        @events = Event.where(category_id: @category_id).order("created_at DESC")
    end
    # The above code = If there's no category found then all the events are listed
    # If there is then it will show the EVENTS under each category only
end

def show
end

def new
    @event = current_user.events.build
    # this now builds out from a user once devise gem is added
    # after initially having an argument of Event.new
    # this assigns events to users
end
# both update and create actions below use event_params as their argument with    an if/else statement 
def create
    @event = current_user.events.build(event_params)
    # as above this now assigns events to users
    # rather than Event.new

    if @event.save
        redirect_to @event, notice: "Congratulations, you have successfully created a new event."
    else
        render 'new'
    end
end

def edit
    # edit form
    # @edit = Edit.find(params[:id])
    @event = current_user.events.find(params[:id])
end

def update
    if @event.update(event_params)
        redirect_to @event, notice: "Event was successfully updated!"
    else
        render 'edit'
    end
end

def destroy
    @event.destroy
    redirect_to root_path
end

private

def event_params
    params.require(:event).permit(:title, :location, :date, :time, :description, :number_of_spaces, :is_free, :price, :organised_by, :organiser_profile, :url, :image, :category_id)
    # category_id added at the end to ensure this is assigned to each new event created
end

def find_event
    @event = Event.find(params[:id])
end

结束

用户控制器 -

class UsersController < ApplicationController
before_action :authenticate_user!


def new
    @user = User.new
end


def show
    @user = User.find(params[:id])

end

def create
    @user = User.new(user_params)

        if @user.save
            flash[:success] = "Welcome to Mama Knows Best"
            session[:uid] = @user.id
            redirect_to root_path
        else
            render 'new'
        end
end

def edit  
    @user =  current_user                             
end  

def update
    @user = current_user
        if @user.update(user_params)
            flash[:success] = "Profile successfully updated!"
            redirect_to root_path
        else
            render 'edit'
        end
end


private

def user_params
    params.require(:user).permit(:name, :username, :biography, :email, :url)

end 


end

显示页面-

<%= image_tag @event.image.url %>

<h1><%= @event.title %></h1>
<p>Location </p>
<p><%= @event.location %></p>
<p>Date</p>
<p><%= @event.date.strftime('%A, %d %b %Y') %></p>
<p>Time</p>
<p><%= @event.time.strftime('%l:%M %p') %></p>
<!-- above expresses date and time as per UK expectations -->
<p>More details</p>
<p><%= @event.description %></p>
<p>Number of Spaces available</p>
<p><%= @event.number_of_spaces %></p>
<% if @event.is_free? %>
<p>This is a free event</p>
<% else %>
<p>Cost per person</p>
<p><%= @event.price %></p>
<% end %>
<p>Organiser</p>
<p><%= @event.organised_by %></p>
<p>Organiser Profile</p>
<button><%= link_to "Profile", user_path %></button>
<p>Link to Organiser site</p>
<button><%= link_to "Organiser site", @event.url %></button>

<p>Submitted by</p> 
<p><%= @event.user.name %></p>


<% if user_signed_in? and current_user == @event.user %>
<%= link_to "Edit", edit_event_path %>
<%= link_to "Delete", event_path, method: :delete, data: { confirm: "Are you   sure?"} %>
<%= link_to "Back", root_path %>
<% else %>
<%= link_to "Back", root_path %>
<%= link_to "Book the Event", new_event_booking_path(@event) %>
<% end %>

路线 -

Rails.application.routes.draw do


  devise_for :users, :controllers => { registrations: 'registrations' }  



  resources :users
  resources :events do

    resources :bookings
  end
  # get 'welcome/index'


  authenticated :user do
    root 'events#index', as: "authenticated_root"
  end


    root 'welcome#index'

  # the above method comes from devise and allows for the site to have a home page
  # for users not signed in and one for when they are signed in


end

我没有在部分表单上添加与用户个人资料相关的任何内容,因为我认为它不相关。任何帮助将不胜感激。

【问题讨论】:

  • Event 是否与User 有任何关联?
  • &lt;button&gt;&lt;%= link_to "Profile", user_path %&gt;&lt;/button&gt; user_path` 是解析为 UserController#show 并期望一个参数的助手。做user_path(current_user)
  • 我试过 current_user 还是不行。
  • 是的,用户有_许多事件和事件属于_用户

标签: ruby-on-rails ruby activerecord


【解决方案1】:

user_path 是 Rails 中的路径助手,它解析为 /users/:id 的 RESTful 路由。这进入UserController#show 并期望params 哈希包含:id

对于您的情况,您缺少论点。你需要做的:

<button><%= link_to "Profile", user_path(current_user) %></button>

它会自动获取 id 并将其传递给 params hash 为:{:id =&gt; 7} Doc

您可能还想修复其他此类助手调用:

event_path edit_event_path 带有适当的参数。

【讨论】:

  • 尝试user_path(@event.user) 只是为了检查它是路由问题还是当前用户的
  • 不,也不是。
【解决方案2】:

您使用什么来进行用户身份验证、设计或类似的 gem?你自己建的吗?如果是这样,您在会话助手中定义了 current_user 吗?下面的代码是如何定义 current_user 的(一个哈特尔 Rails 教程)。这将允许您在视图和控制器中使用 current_user。

def current_user
    if (user_id = session[:user_id])
      @current_user ||= User.find_by(id: user_id)
    elsif (user_id = cookies.signed[:user_id])
      user = User.find_by(id: user_id)
      if user && user.authenticated?(:remember, cookies[:remember_token])
        log_in user
        @current_user = user
      end
    end
  end

我还注意到在您的用户控制器中的 def create 下。我相信它应该是 session[:id] 而不是 session[:uid]。如果不是这种情况,请原谅。希望这会有所帮助。

【讨论】:

  • 我正在使用设计,但为了创建用户配置文件,我对其进行了一些构建。这是我的路线文件 -
  • 抱歉 - 我在上面添加了路线。
  • 运行 $ bundle exec rake routes 时的输出是什么?我的用户和事件布局类似, 在我的事件页面上运行良好。要检查的另一件事是,您的事件数据库表是否在创建事件时记录了正确的用户 ID?
  • 我该如何检查,因为我认为这可能与它有关。错误消息是说明事件 ID 号而不是用户 ID。
  • 您使用什么样的数据库进行开发?如果您使用的是 SQLite,SQLite 的 DB 浏览器运行良好(在此处下载:sqlitebrowser.org)。下载您的 db/development.sqlite3 文件并在 db 浏览器中查看。您还可以通过搜索 >> Event.all 查看 Rails 控制台中的所有条目
【解决方案3】:

为了重申您的问题,您希望活动页面上的链接指向活动组织者的个人资料页面吗?

<p>Organiser Profile</p>
<button><%= link_to "Profile", user_path(@event.user) %></button>

【讨论】:

  • 干杯 - 解决了它。
猜你喜欢
  • 2016-05-11
  • 2012-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-29
  • 1970-01-01
相关资源
最近更新 更多