Search code examples
htmlruby-on-railsrubyrubygemsrubymine

How do I redirect the to index after submitting a new record at the front-end? [Rubymine 2020.2.3, Ruby.2.7.2p137, gem 3.1.2]


I am struggling with a college project course, and I have been stuck with this error for weeks now, despite the suggestions provided by colleagues and tutors.

In my create method for a given table. I am trying to have the page containing the forms for new record entries redirect back to the index page after saving. Instead, I get redirected to this error instead, highlighting @courier=Courier.new(courier_new_path) with the error stating that it is not a hash, and would not redirect me back into index. However, when manually searching the index, I see that the data string would indeed get updated.

I have tried renaming the path label, but Rubymine prompt suggestions appear limited, and any further deviation would cause a different error

The following is the create method in the controller page (courier_controller.rb):

def create
@courier=Courier.new(params.require(:courier).permit(:courier_name,:courier_email))
@courier.save
redirect_to courier_path(@courier)
@courier=Courier.new(courier_new_path)
if @courier.save
  redirect_to(:controller=>'courier' ,:action=>'index')
else
  render('new')
end 
end

Here is the code for the form page (courier/new/html.erb):

<h1>Courier#new</h1>
<p>Find me in app/views/courier/new.html.erb</p>
<%= form_with scope: :courier, :url => {:action => 'create'}, local: true do |f| %>

  <p>
    <%= f.label :courier_name %><br/>
    <%= f.text_field :courier_name %>
  </p>

  <p>
    <%= f.label :courier_email %><br/>
    <%= f.text_field :courier_email %>
  </p>

  <p>
    <%= f.submit %>
  </p>
<% end %>

I have tried renaming @courier as Courier.new(courier_create_path) or Courier.nww(courier_path), I have tried looking for arguments using a hash form, but none seemed equivocal nor translatable as a solution to my problem.

Any suggestions would help. This is part of a college project, and as a multimedia student not as savvy in programming compared to fellow peers, I would highly appreciate suggestions that I can try out.

Many thanks in advance.


Solution

  • Has anyone tried to explain what is actually going on in your create method? I've added comments after each line to say what that line is doing.

    def create
      @courier=Courier.new(params.require(:courier).permit(:courier_name,:courier_email))
    # use the params to build a new courier record (the permit part is usually in a separate method that other methods can access but it works this way)
      @courier.save
      # Save the new courier record to the database
      redirect_to courier_path(@courier)
      # Send the user back to the "show" page of the courier record (not index!)
      @courier=Courier.new(courier_new_path)
      # this makes no sense, you are trying to create a new courier object using a path method
      # Basically you are saying: @courier = Courier.new('/courier/new')
      if @courier.save
       #you are trying to save this record that will fail because you can't create a courier by passing it a url
        redirect_to(:controller=>'courier' ,:action=>'index')
         #send the user to the index page of the courier views. 
      else
        render('new')
         #something went wrong so go back to the new courier form.
      end 
    end
    

    When your program gets to line 4 redirect_to courier_path(@courier) it is going to exit the create method and send the user to http://my_app:3000/couriers/1 where the number 1 would be the ID in the database of the record you just created. This would relate to the file in your app in app/views/couriers/show.html.erb. It sounds like you want to get to http://my_app:3000/couriers which presents the user with the file app/views/couriers/index.html.erb Not sure why you are doing anything after that line.

    Also it is unclear what error you are getting. You need to look at your webserver console, the place where you run "rails s" that shows all the communications between the browser and your app. find the stack trace that starts with the actual error, and add that to your question above (don't paste it in a comment, it will be too long and impossible to read).

    I think you just need:

    def create
      @courier=Courier.new(params.require(:courier).permit(:courier_name,:courier_email))
      if @courier.save
        redirect_to @courier #if you want to redirect to their 'show" page
      else
        render('new')
         #something went wrong so go back to the new courier form.
      end 
    end
    

    What might be confusing to a new programmer is that Rails is doing so much "magic" behind the scenes it gets very confusing if you don't already know the underlying concepts happening behind the scenes. You are saying redirect_to(:controller=>'courier' ,:action=>'index') which specifically says "go to the index page of the couriers" but you can say redirect_to @courier and it will assume that you want to go to the page that shows the record of the courier you just created. If you really want to go the table that shows all of the couriers you would replace that with redirect_to :couriers The symbol :couriers tells it to go to the index method of the couriers controller.