2015-04-15 3 views
0

A RoR начинающий здесь. Я пытаюсь реализовать страницу «Мои продукты», чтобы показать все продукты, добавленные текущим пользователем. В настоящее время я установил страницу «Все продукты» в качестве моего индекса root «product # index». Мой продукт имеет контроллер, но мой Пользователь не является контроллером, потому что я использую Devise. У меня есть несколько вопросов, которые я все еще не мог понять.Ruby Rails Path Показать все товары от пользователя

Поскольку в настоящее время

Продукт

belongs_to :user 

Пользователь

has_many :products 

маршруты

devise_for :users 
resources :products 

рейк маршруты У меня есть

new_user_session  GET /users/sign_in(.:format)     devise/sessions#new 
     user_session POST /users/sign_in(.:format)     devise/sessions#create 
destroy_user_session DELETE /users/sign_out(.:format)     devise/sessions#destroy 
     user_password POST /users/password(.:format)     devise/passwords#create 
    new_user_password GET /users/password/new(.:format)    devise/passwords#new 
    edit_user_password GET /users/password/edit(.:format)   devise/passwords#edit 
         PATCH /users/password(.:format)     devise/passwords#update 
         PUT /users/password(.:format)     devise/passwords#update 
cancel_user_registration GET /users/cancel(.:format)     devise/registrations#cancel 
    user_registration POST /users(.:format)       devise/registrations#create 
new_user_registration GET /users/sign_up(.:format)     devise/registrations#new edit_user_registration GET /users/edit(.:format)      devise/registrations#edit 
         PATCH /users(.:format)       devise/registrations#update 
         PUT /users(.:format)       devise/registrations#update 
         DELETE /users(.:format)       devise/registrations#destroy 
products    GET /products(.:format)      products#index 
         POST /products(.:format)      products#create 
      new_product GET /products/new(.:format)     products#new 
     edit_product GET /products/:id/edit(.:format)    products#edit 
       product GET /products/:id(.:format)     products#show 
         PATCH /products/:id(.:format)     products#update 
         PUT /products/:id(.:format)     products#update 
         DELETE /products/:id(.:format)     products#destroy 

В настоящее время, что я имею в виду для достижения этой цели:

Создать UserController иметь @user = User.all то, потому что с объединением я могу использовать @ user.product. (Я видел, как некоторые люди говорили, что я не должен создавать новый контроллер из-за Devise?) Однако я попытался протестировать консоль rails перед выполнением этой реализации.

product = Product.first 
product.user #here I get all details about user 

user = User.first 
user.product #here I get error. Why it works for product to find user but not both ways? 

Далее, это то заставляет меня задаться вопросом, как создать настроить маршрут, чтобы получить путь/пользователей /: ID/продукты. Должен ли я использовать вложенный ресурс?

Следующий вопрос, я пытался иметь

resources :users do 
    resources :products 
end 

resources :products 

я снова набрал в реках маршрутах. Я смущен

user_products GET /users/:user_id/products(.:format)   products#index 
products GET /products(.:format)       products#index 

Вопрос:

  1. Can 2 путь имеет тот же контроллер # Action?
  2. user_products_path и products_path - это 2 разных пути, где user_products_path представляет пользовательский продукт. и products_path представляет собой все продукты

Извините за длинный пост. Я действительно хочу прояснить эти вещи. Большое спасибо, если вы могли бы помочь! :)

+0

попробовать user.products – djrock

ответ

2

user.product #here Я получаю ошибку. Почему он работает для продукта, чтобы найти пользователя, но не в обоих направлениях?

Как User has_many :products, вам нужно использовать правильное имя ассоциации, как:

user.products # it will give you all products of an user 

Can 2 путь имеет тот же контроллер # Action?

Одним словом, ДА.Можно указать контроллер и имя действия явно в вашем route.rb как:

get 'users/:id/products' => 'products#index', :as => :user_products_path 

Примечание, что в вашем случае, это будет идти в products#index по умолчанию также.

user_products_path и products_path - это два разных пути, где user_products_path представляет продукт пользователя. и products_path представляет собой все продукты

Правильно, это абсолютно нормально. Когда вы используете devise, вам не нужно использовать параметр id, исходящий из URL-адреса i.e. users/:id/products. Вы можете получить пользователя напрямую от current_user, что также лучше с точки зрения безопасности. Имейте в виду, что если у вас есть роль администратора, который может видеть детали каждого пользователя, тогда вам нужно будет управлять id в этом случае.

+0

Предполагая, что я решил создать новую страницу, чтобы показать «Мои продукты», что я сделал только сейчас был: 1. В Products Controller, Защиту SHOWALL @products = current_user.products концевые 2. Создана showall.html.erb под продуктами вид 3. маршрута ресурсов: продукты делают ПОЛУЧАЮТ: SHOWALL концевых реки маршрутов и я закончил с product_showall GET /products/:product_id/showall(.:format) продукты # showall Как сделать Я избавляюсь от product_id? – ikanyu

+0

Если этот ответ решил вашу проблему, вам следует пересмотреть и создать новый вопрос для вышеупомянутой проблемы, упомянутой в вашем комментарии.Это сэкономит ваши текущие запросы, чтобы они исчезли, а другие пользователи смогут получить выгоду от вашего вопроса. Вы можете добавить здесь URL нового вопроса, чтобы мы могли помочь вам. – RAJ

+0

Отмечено. Спасибо за напоминание. Другой вопрос, касающийся того, как изменить шаблон URL. http://stackoverflow.com/questions/29652146/modify-url-pattern-ruby-rails Спасибо! – ikanyu

0

Поскольку вы только начинаете, я буду придерживаться простого примера, имея легко читаемую логику. Тем не менее, есть более эффективные способы настройки и оптимизации этого, так что вы не полагаетесь на операторы if в вашем контроллере.

class ProductsController < ApplicationController 
    def index 
    if params[:user_id] 
     @user = User.find(params[:user_id]) 
     @products = @user.products.all 
    else 
     @products = Product.all 
    end 
    end 
end 

Одна из причин, почему это плохая практика, что вы полагаетесь на user_id паров быть действительными. Если параметр user_id недействителен, то вторая строка @products = @user.products.all вернет undefined method for Nil class.

Кроме того, в ваших представлениях, если вы ссылаетесь на @user, тогда вы получите сообщение об ошибке, если вы просто перечисляете все продукты.

Кроме того, нет никакой безопасности, если кто-либо может видеть чьи-либо продукты, если они знают или пытаются угадать id пользователя.

Однако это должно работать в вашем случае. Вы также можете подумать, что если присутствует user_id, тогда вызывается current_user.products.all, чтобы он возвращал только текущие пользовательские продукты, а не конкретные user_id. Тем не менее, это действительно зависит от того, как вы разрабатываете приложение, которое определит лучший маршрут.

Что я, как правило, делаю, если маршрут /products должен быть для административного уровня, я буду namespace и поставлю соответствующую защиту вокруг пространства имен, чтобы она не позволяла общим пользователям получать к ней доступ, а администраторов сайта.

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