Search code examples
ruby-on-railsnomethoderror

I'm getting a NoMethodError on rails, unsure how to access a model through another model


Im writing a game on rails, and am trying to allow a user to create their mine (its a mining game). I have a table for the users, and a table for mines. Each user has a ref. ID on their entry, pointing to their mine's ID in the mine table.

I'm getting an error when I try to visit /users/1/mines/new.

undefined method `mines_path'

I can't figure out why.

form in New:

<%= form_for [@mine] do |f| %>
    <%= f.label :name %>
    <%= f.text_field :name %><br>

    <p>Depth: <%= @mine.depth %></p>

    <%= f.submit "Submit", id: "submit" %>
<% end %>

Controller:

def new
 @user = User.find(params[:user_id])
 @mine = @user.mines.new
end

def create
 @mine = @user.mines.create(mine_params)
 if @mine.save
  redirect_to users_mines_path
 else
  render new_mines_path
 end
end

routes:

root 'welcome#index'
resources :sessions, only: [:create]
resources :users do
  resources :mines
end
resources :tools, only: [:create]

How can I create a new mine THROUGH the user? Am I doing this correctly in my controller? Thanks!


Solution

  • In your routes you have mines nested inside users so you need to change your form to something like this:

    <%= form_for [@user,@mine] do |f| %>
      <%= f.label :name %>
      <%= f.text_field :name %><br>
    
      <p>Depth: <%= @mine.depth %></p>
    
      <%= f.submit "Submit", id: "submit" %>
    <% end %>
    

    OR

    You can specify url option with your path:

    <%= form_for @mine, url: user_mines_path(@user)  do |f| %>
      <%= f.label :name %>
      <%= f.text_field :name %><br>
    
      <p>Depth: <%= @mine.depth %></p>
    
      <%= f.submit "Submit", id: "submit" %>
    <% end %>
    

    For details on forms refer to Form Helpers

    Also as @Vimsha pointed out in your controller you need to use .new instead of .create as create will initialize and save your your mine.

    def create
      @mine = @user.mines.new(mine_params)
      if @mine.save
        redirect_to user_mines_path
      else
        render new_user_mine_path
      end
    end