【问题标题】:Rails: Why can't I save a new model Instance to the database?Rails:为什么我不能将新模型实例保存到数据库中?
【发布时间】:2021-07-29 23:33:30
【问题描述】:

我的控制器的#create 操作如下所示。我不知道,为什么 ruby​​/rails 不接受参数分配,因此我保存的对象具有“nil”属性

def create
  @new_page = Page.new 
  @new_page.slug = helpers.create_slug_from_title(params[:title])

  # Yes, I should also save the rest of params and make
  # params a strongparameter object
        
  # how to handle errors on create ?
  begin 
    @new_page.save
  rescue
  end

end

如果有任何提示,我将不胜感激。

你的

冯·斯波茨

PS:在控制台中看起来并没有什么不同。

2.7.0 :038 > pn = Page.new
2.7.0 :039 > pn.slug = "index-page"
2.7.0 :040 > pn.slug
 => "index-page" 
2.7.0 :041 > pn
 => #<Page id: nil, text: nil, slug: nil, created_at: nil, updated_at: nil, title: nil, streams_id: nil> 
2.7.0 :042 > pn.save
   (0.2ms)  begin transaction
  Page Create (0.6ms)  INSERT INTO "pages" ("created_at", "updated_at") VALUES (?, ?)  [["created_at", "2021-05-07 17:01:15.111775"], ["updated_at", "2021-05-07 17:01:15.111775"]]
   (31.5ms)  commit transaction
 => true 
2.7.0 :043 > Page.all
Page Load (0.2ms)  SELECT "pages".* FROM "pages" LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Page id: 1, text: nil, slug: nil, created_at: "2021-05-07 15:40:59", updated_at: "2021-05-07 15:40:59", title: nil, streams_id: nil>, #<Page id: 2, text: nil, slug: nil, created_at: "2021-05-07 16:46:00", updated_at: "2021-05-07 16:46:00", title: nil, streams_id: nil>, #<Page id: 3, text: nil, slug: nil, created_at: "2021-05-07 17:01:15", updated_at: "2021-05-07 17:01:15", title: nil, streams_id: nil>]> 
2.7.0 :044 > 

PPS:具有创建操作和 page_params 的新控制器,由 max 友情发布

class PagesController < ApplicationController
    
    def home
  end
    
    def show
        @page = Page.where(slug: params[:slug])
    end
    
    def new
        @new_page = Page.new
    end
    
    def edit
        @page = Page.where(slug: params[:slug])
        # error if @page.nil?
    end
    
# POST /pages
  def create
    @page = Page.new(page_params) do |page|
      # smelly - should be handled inside the model not by the controller
      page.slug = helpers.create_slug_from_title(page.title)
    end
        
    if @page.save
      redirect_to @page, status: :created
    else
      render :new, status: :unprocessable_entity
    end
  end
        
  private

  def page_params
    params.require(:page)
                    .permit(:slug, :title, :text)
  end
        
end

【问题讨论】:

  • @new_page.valid?; @new_page.errors 返回什么?
  • 你好塞巴斯蒂安。 (byebug) @new_page.valid? true (byebug) @new_page.errors #&lt;ActiveModel::Errors:0x00007f0c9c8bf6a0 @base=#&lt;Page id: 2, text: nil, slug: nil, created_at: "2021-05-07 16:46:00", updated_at: "2021-05-07 16:46:00", title: nil, streams_id: nil&gt;, @messages={}, @details={}&gt; 但问题不在于储蓄。问题已经是assignment了。如果我尝试分配一个值并调用我刚刚“分配”一个值的相同属性,它将返回nil。再见!
  • 您的模型中是否有任何东西可能会在插入之前修改 slug?
  • 我猜测为什么你的 slug 被保存为 nil 是因为你的模型中有 attr_accessor :slug

标签: ruby-on-rails model-view-controller orm controller


【解决方案1】:
class PagesController
  # POST /pages
  def create
    @page = Page.new(page_params) do |page|
      # smelly - should be handled inside the model not by the controller
      page.slug = helpers.create_slug_from_title(page.title)
    end
    if @page.save
      redirect_to @page, status: :created
    else
      render :new, status: :unprocessable_entity
    end
  end

  private

  def page_params
    params.require(:page)
          .permit(:foo, :bar, :title)
  end
end

您通过重新呈现表单来处理经典网络应用程序中的无效用户输入。 begin ... rescue 不会在这里工作,因为 .save 不会引发。 save! 确实如此,但它在这里的使用是有问题的,因为例外情况应该用于例外情况 - 无效的用户输入是日常事件。

在表单上,​​您使用错误对象向用户显示验证错误:

<%= form_with(model: @page) do |f| %>
  <% # @todo extract this into a partial %>
  <% if f.object.errors.any? %>
  <div id="error_explanation">
    <h2><%= pluralize(f.object.errors.count, "error") %> prohibited this page from being saved:</h2>
    <ul>
    <% f.object.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
  <% end %>
  
  <div class="field">
    <%= f.label :title %>
    <%= f.text_field :title %>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

【讨论】:

  • 由于基于Comment 的对象不是无效的,您可能希望运行验证?
  • 您好,谢谢。现在它抱怨undefined local variable or method 'page_params' for #&lt;PagesController:0x000056544f0af830&gt;
  • 工程师你好,显然自从我上次使用 Rails 以来发生了很大变化。我现在是否需要对 params 哈希进行强参数化?我的意思是,我将阅读 rails 6 的验证指南,但您能否快速/友好地告诉我,我必须/如何验证模型中的内容?
  • 不要在 Rails 模型中使用 attr_accessor。 ActiveRecord 将根据您的数据库模式自动创建 setter/getter。如果您有与数据库列不对应的属性,请使用属性 API。 metova.com/rails-5-attributes-api
  • 我注释掉了 attr_accessor。正如我所说,自从我上次使用 Rails 以来,显然发生了很多变化。感谢您的王牌帮助。现在我遇到了与#show-action 对应的视图的问题。但我想我会解决这个问题的。如果不是,它的问题域是另一个域。感谢您解决问题。再见麦克斯和工程师mnky
猜你喜欢
  • 1970-01-01
  • 2022-01-18
  • 2021-02-12
  • 2012-07-05
  • 1970-01-01
  • 2013-06-11
  • 1970-01-01
  • 2016-05-07
  • 1970-01-01
相关资源
最近更新 更多