2015-12-12 5 views
1

Этот код основан на учебнике Ruby on Rails от Michael Hartl. Я создал assigned действие в моей users_controller сНет совпадений маршрута в коде Rails

def assign 
    puts "in assign..." 
    @scout = User.find(params[:follower_id]) 
    @der = User.find(params[:followed_id]) 
end 

Я понимаю, что ничего не делает в настоящее время, но в _follow частичной, у меня есть

<%= form_for @user, url: { action: "assign" } do |f| %> 
    <div><%= hidden_field_tag :follower_id, @user.id %></div> 
    <%= f.label :followed_id, "Assign #{@user.name} to" %> 
    <%= f.collection_select :following, @ders, :id, :name, prompt: true %> 
    <%= f.submit "Assign", class: "btn btn-primary" %> 
<% end %> 

Но я получаю ошибку No route matches {:action=>"assign", :controller=>"users", :id=>"4"}. Я новичок в рельсах, так что это может быть просто глупый вопрос. Что я делаю не так? Нужно ли мне изменить файл routes.rb? Кроме того, если я попробовал <%= form_for @user do |f| %>, как контроллер знает, какое действие использовать? Это основано на действии, отображающем форму?

Edit: мой routes.rb файл

Rails.application.routes.draw do 
    root    'static_pages#home' 
    get 'help' => 'static_pages#help' 
    get 'about' => 'static_pages#about' 
    get 'contact' => 'static_pages#contact' 
    get 'signup' => 'users#new' 
    get 'login' => 'sessions#new' 
    post 'login' => 'sessions#create' 
    delete 'logout' => 'sessions#destroy' 
    resources :users do 
    member do 
     get :following, :followers 
    end 
    end 
    resources :account_activations, only: [:edit] 
    resources :password_resets,  only: [:new, :create, :edit, :update] 
    resources :relationships,  only: [:create, :destroy] 
end 

Edit 2: HTML генерируется @form_for блок Рича является

<form class="edit_user" id="edit_user_5" action="https://stackoverflow.com/users/5/assign" accept-charset="UTF-8" method="post"> 
    <input name="utf8" type="hidden" value="✓"> 
    <input type="hidden" name="_method" value="patch"> 
    <input type="hidden" name="authenticity_token" value="..."> 
    <label for="user_followed_id">Assign Mr. Marley Muller to</label> 
    <select name="user[following]" id="user_following"> 
    <option value="1">Example User</option> 
    <option value="2">Matthew Swartz</option> 
    <option value="3">Joseph Swartz</option> 
    </select> 
    <input type="submit" name="commit" value="Assign" class="btn btn-primary"> 
</form> 

Который имеет смысл, почему я сейчас получаю не могу найти id, так как он не отправляет реальный идентификатор (edit_user_5)

Редактировать 3: Вот параметры, передаваемые для запроса

Started PATCH "https://stackoverflow.com/users/6/assign" for 68.100.59.128 at 2015-12-15 03:54:39 +0000 
Processing by UsersController#assign as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"...", "user"=>{"following"=>"2"}, "commit"=>"Assign", "id"=>"6"} 
    User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 6]] 
Unpermitted parameter: following 
    User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", nil]] 
Completed 404 Not Found in 9ms (ActiveRecord: 1.0ms) 

ActiveRecord::RecordNotFound (Couldn't find User with 'id'=): 
    app/controllers/users_controller.rb:69:in `assign' 

Редактировать 4: При следующем файле маршрутов,

Rails.application.routes.draw do 
    root    'static_pages#home' 
    get 'help' => 'static_pages#help' 
    get 'about' => 'static_pages#about' 
    get 'contact' => 'static_pages#contact' 
    get 'signup' => 'users#new' 
    get 'login' => 'sessions#new' 
    post 'login' => 'sessions#create' 
    delete 'logout' => 'sessions#destroy' 
    resources :users do 
    member do 
     get :following, :followers 
     match :assign, to: :assign, via: [:post, :patch] 
    end 
    end 
    resources :account_activations, only: [:edit] 
    resources :password_resets,  only: [:new, :create, :edit, :update] 
    resources :relationships,  only: [:create, :destroy] 
end 

и следующая форма для присвоения одному пользователю следовать за другим,

<%= form_for @user, url: { action: "assign" } do |f| %> 
    <%= f.label :follower_id, "Assign #{@user.name} to" %> 
    <%= f.collection_select :following, @ders, :id, :name, prompt: true %> 
    <%= f.submit "Assign", class: "btn btn-primary" %> 
<% end %> 

Я получаю ActiveRecord::RecordNotFound in UsersController#assign ошибку Couldn't find User with 'id'= , но со следующими параметрами:

{"utf8"=>"✓", 
"_method"=>"patch", 
"authenticity_token"=>"...", 
"user"=>{"following"=>"3"}, 
"commit"=>"Assign", 
"id"=>"4"} 

Идентификаторы верны: "user"=>{"following"=>"3"} и "id"=>"4", я считаю, что я просто пытаюсь получить к ним доступ неправильно. Это действие назначает в пользовательском контроллере:

def assign 
    @scout = User.find(params[:id]) 
    @der = User.find(params_hash[:followed_id]) 
    # make scout follow der here 
    redirect_to @scout 
end 

Мысли?

+0

показать свой 'routes.rb' файл пожалуйста. –

+0

Как это работает, вам нужно определить маршрут в файле 'routes.rb', который отображается на действие контроллера. Итак, сообщение об ошибке, которое вы получили, потому что либо вы не определили маршрут, либо вы сделали это неправильно. –

+0

@KMRakibulIslam, см. Мое редактирование – mjswartz

ответ

0

Оказывается, это была комбинация Эму и ответы Рича. Форма в HTML является

<%= form_for @user, url: { action: "assign" } do |f| %> 
    <%= f.label :follower_id, "Assign #{@user.name} to" %> 
    <%= f.collection_select :following, @ders, :id, :name, prompt: true %> 
    <%= f.submit "Assign", class: "btn btn-primary" %> 
<% end %> 

С действием контроллера

def assign 
    @scout = User.find(params[:id]) 
    @der = User.find(params[:user][:following]) 
    @scout.follow(@der) 
    redirect_to @scout 
end 

и маршрутов как

Rails.application.routes.draw do 
    root    'static_pages#home' 
    get 'help' => 'static_pages#help' 
    get 'about' => 'static_pages#about' 
    get 'contact' => 'static_pages#contact' 
    get 'signup' => 'users#new' 
    get 'login' => 'sessions#new' 
    post 'login' => 'sessions#create' 
    delete 'logout' => 'sessions#destroy' 
    resources :users do 
    member do 
     get :following, :followers 
     match :assign, to: :assign, via: [:post, :patch] 
    end 
    end 
    resources :account_activations, only: [:edit] 
    resources :password_resets,  only: [:new, :create, :edit, :update] 
    resources :relationships,  only: [:create, :destroy] 
end 
7

В вашем routes.rb файл, который вы должны определить маршрут для конкретного действия контроллера вроде этого:

resource :users do 
    member do 
    post 'assign' # change the request method to 'put' 
    end 
end 

Он будет генерировать маршрут для вашего назначить метод в контроллере, как: users/4/assign

для получения дополнительной информации посетите guides

+0

См. Комментарий, который я разместил под ответом @ Rich – mjswartz

+0

@mjswartz, вы отправляете форму существующему объекту. Таким образом, действие 'post' будет' put'. – Emu

2

чтобы добавить ответ Emu «s, т он код, который у вас не будет работать ...

def assign 
    puts "in assign..." 
    @scout = User.find(params[:follower_id]) 
    @der = User.find(params[:followed_id]) 
end 

В PARAMS вы получите от form_for объекта будет структурирована следующим образом:

params[:user][:follower_id] 
params[:user][:followed_id] 

Вы должны были бы использовать следующее:

#app/controllers/users_controller.rb 
class UsersController < ApplicationController 
    def assign 
     @scout = User.find params[:id] 
     @der = User.find params_hash[:followed_id] 
    end 

    private 

    def params_hash 
     params.require(:user).permit(:followed_id) 
    end 
end 

Вы также могли бы избавиться поля hidden в вашей форме, если вы используете тот же объект @user, чтобы заполнить его:

<%= form_for @user, url: { action: "assign" } do |f| %> 
    <%= f.label :followed_id, "Assign #{@user.name} to" %> 
    <%= f.collection_select :following, @ders, :id, :name, prompt: true %> 
    <%= f.submit "Assign", class: "btn btn-primary" %> 
<% end %> 

Update

Вам нужно включить :assign в маршрутах:

Rails.application.routes.draw do 
    root    'static_pages#home' 
    resources :static_pages, only: [], path: "" do 
    collection do 
     get :help, :about, :contact 
    end 
    end 

    resources :sessions, only: [:new, :create, :destroy], path_names: {new: "login", create: "login", destroy: "logout"} 

    resources :users, path_names: { new: "signup" } do 
    member do 
     get :following, :followers, :assign 
    end 
    end 
    resources :account_activations, only: [:edit] 
    resources :password_resets,  only: [:new, :create, :edit, :update] 
    resources :relationships,  only: [:create, :destroy] 
end 
+0

Я применил ваши и @ изменения Emu, но я получаю следующую ошибку: 'ActionController :: RoutingError (Нет маршрутов соответствует [PATCH]"/users/7/assign "):' – mjswartz

+0

Это потому, что '@ emu' поставил ваши маршруты к 'post' - вы должны сделать это' match: assign, to:: assign, via: [: post,: patch] '- это должно решить проблему –

+0

Богатый, я добавил фрагмент кода из этого комментария, но я 'Получает ошибку 'ActiveRecord :: RecordNotFound в UsersController # assign' с' Не удалось найти пользователя с' id '= '. См. Мое редактирование для HTML, сгенерированного блоком 'form_for'. – mjswartz

 Смежные вопросы

  • Нет связанных вопросов^_^