首页 > 解决方案 > 在表单对象中找不到没有 ID 的用户

问题描述

你可以帮帮我吗?我得到一个错误找不到没有ID的用户,我正在考虑像博客服务一样制作,我想在没有accept_nested_attributes_for的情况下实现嵌套属性,所以我一直在使用表单对象,但我无法发送表单对象用户的范围,

控制器

    class BlogsController < ApplicationController
    before_action :authenticate_user! 
  def index
    @current = current_user
  end

  def new
    @blogs = BlogForm.new

  end

  def create

    @blogs = BlogForm.new(blog_params)
    if @blogs.save
      redirect_to user_blogs_path
    else
    end

  end

  def edit
  end

  def show
  end

  private

  def blog_params
    params.require(:blog_form).permit(:title , :content , :user_id)
  end
end

表单html

<%= form_with model: @blogs , url: user_blogs_path,local: true do |f| %>

<%  f.label :title %>
<%= f.text_field :title %>

<%  f.label :content %>
<%= f.text_area :content %>

<%  f.label :user_id %>
<% f.hidden_field :user_id ,   value: current_user.id%>

<%= f.submit "create", class: "btn btn-primary" %>
<% end %>

blog_form

class BlogForm
  include ActiveModel::Model

  attr_accessor :title, :content, :user_id
  def to_model
    @user = User.find(user_id)
    @blogs = @user.blogs.new(title: title , content: content , user_id: user_id)
  end

  def save
    return false if invalid
    to_model.save
  end
end

博客.rb

 class Blog < ApplicationRecord
  belongs_to :user
  validates :title ,presence: true
  validates :content ,presence: true

end

用户.rb

 class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  has_many :blogs

  def email_required?
   false
 end
 def email_changed?
   false
 end
 def will_save_change_to_email?
  false
end

end

日志

 ActionView::Template::Error (Couldn't find User without an ID):
    1: <%= form_with model: @blogs , url: user_blogs_path,local: true do |f| %>
    2: 
    3: <%  f.label :title %>
    4: <%= f.text_field :title %>

app/forms/blog_form.rb:6:in `to_model'
app/views/blogs/shared/_form.html.erb:1
app/views/blogs/new.html.erb:4
Started GET "/users/1/blogs/new" for 127.0.0.1 at 2020-01-19 16:29:03 +0900
Processing by BlogsController#new as HTML
  Parameters: {"user_id"=>"1"}
  Rendering blogs/new.html.erb within layouts/application
  Rendered blogs/shared/_form.html.erb (Duration: 3.0ms | Allocations: 1143)
  Rendered blogs/new.html.erb within layouts/application (Duration: 10.5ms | Allocations: 1228)
Completed 500 Internal Server Error in 16ms (ActiveRecord: 0.0ms | Allocations: 1715)



ActionView::Template::Error (Couldn't find User without an ID):
    1: <%= form_with model: @blogs , url: user_blogs_path,local: true do |f| %>
    2: 
    3: <%  f.label :title %>
    4: <%= f.text_field :title %>

app/forms/blog_form.rb:6:in `to_model'
app/views/blogs/shared/_form.html.erb:1
app/views/blogs/new.html.erb:4

之后,我尝试了科里沃德的方法,但我做不到,

rocessing by BlogsController#new as HTML
  Parameters: {"user_id"=>"1"}
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ?  [["id", 1], ["LIMIT", 1]]
  Rendering blogs/new.html.erb within layouts/application
  Rendered blogs/shared/_form.html.erb (Duration: 6.9ms | Allocations: 1082)
  Rendered blogs/new.html.erb within layouts/application (Duration: 9.4ms | Allocations: 1166)
Completed 500 Internal Server Error in 114ms (ActiveRecord: 2.3ms | Allocations: 11134)



ActionView::Template::Error (Couldn't find User without an ID):
    1: <%= form_with model: @blogs , url: user_blogs_path(@user),local: true do |f| %>
    2:
    3: <%  f.label :title %>
    4: <%= f.text_field :title %>

app/forms/blog_form.rb:6:in `to_model'
app/views/blogs/shared/_form.html.erb:1
app/views/blogs/new.html.erb:4

标签: ruby-on-railsformsobject

解决方案


这只是做嵌套资源的一种非常奇怪和尴尬的方式。当您需要在同一个请求中创建或更新两个(或更多)关联记录时,这实际上与嵌套属性几乎没有关系。

# routes.rb
resources :users do
  resources :blogs, 
    only: [:new, :show, :create],
    shallow: true
end
class BlogsController
  before_action :set_user, only: [:new, :create]

  # GET /blogs/1
  def show
    @blog = Blog.find(params[:id])
  end 

  # GET /users/1/blogs/new
  def new
    @blogs = @user.blog.new
  end

  # POST /users/1/blogs
  def create
    @blogs = @user.blog.new(blog_params)
    if @blog.save
      redirect_to @blog
    else
      render :new
    end
  end

  private 
    def set_user
      @user = User.find(params[:user_id])
    end

    def blog_params
      params.require(:blog).permit(:title, :content)
    end
end
<%= form_with model: [@user, @blog], local: true do |f| %>
  <%  f.label :title %>
  <%= f.text_field :title %>
  <%  f.label :content %>
  <%= f.text_area :content %>
  <%= f.submit "create", class: "btn btn-primary" %>
<% end %>

推荐阅读