【问题标题】:Couldn't find User without an ID in form object在表单对象中找不到没有 ID 的用户
【发布时间】:2020-01-20 01:10:35
【问题描述】:

你能帮帮我吗?我得到一个错误找不到没有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

blogs.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-rails forms object


    【解决方案1】:

    路由助手user_blogs_path 可能需要用户的参数。像这样的:

    user_blogs_path(@user)
    

    这一行的内容:

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

    【讨论】:

      【解决方案2】:

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

      # 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 %>
      

      【讨论】:

      • 谢谢max,我可以创建它,最后我想发表评论,如果我实现评论,我认为你的方式,更需要嵌套路由资源,我听说这种方式是糟糕的设计如果你帮助我,你愿意教我如何解决它吗?
      猜你喜欢
      • 2012-05-24
      • 1970-01-01
      • 2019-05-03
      • 2013-03-11
      • 1970-01-01
      • 1970-01-01
      • 2021-01-24
      • 2010-11-21
      • 1970-01-01
      相关资源
      最近更新 更多