简体   繁体   中英

Rails: Why can't I save a new model Instance to the database?

The #create action of my controller looks like the following. I have no idea, why ruby/rails doesn't take the argument assignments and thus the object I am saving has al "nil"-attributes

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

I'd be thankful for any hint.

Yours

von Spotz

PS: In the console things don't look different.

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: The new controller with the create action and page_params as kindly posted by 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
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

You handle invalid user input in a classic web app by re-rendering the form. begin... rescue will not work here as .save does not raise. save! does but its use here is questionable as exceptions should be used for exceptional cases - invalid user input is an everyday event.

On the form you use the errors object to diplay the validation errors to the user:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM