Ruby on Rails - связывание пользователя и контроллера продукта не работает - PullRequest
0 голосов
/ 12 декабря 2018

ОБНОВЛЕНИЕ 2

То, что я до сих пор делал, это рельсы генерируют миграцию add_user_reference_to_products

Затем я сделал

класс AddUserReferenceToProducts

Но я получаю PG :: DuplicateColumn: ERROR: столбец "user_id" отношения "request_items" уже существует.

Когда я ссылаюсь на это (как @ products.user_id) в представлении, оно пустое.Я пытался создать новый продукт, но он не работает.Что я должен делать, как я просто не могу, для моей жизни сейчас, выяснить, что делать сейчас.

ОБНОВЛЕНИЕ

Я хочу сделатьчто-то вроде этого @ products.users.username (если есть другой способ сделать это, пожалуйста, сообщите мне), чтобы отобразить имя пользователя для продукта, который он создал.

В настоящее время я не изменил код, как указано ниже, но если потребуется дополнительная информация, пожалуйста, сообщите мне.Кроме того, если вы сможете предоставить пошаговый процесс, я был бы признателен.

Ответ при условии, что Клайд не работает для меня (неопределенный метод "имя пользователя").

ВОПРОС: Как связать пользовательский контроллер с контроллером продукта, несмотря на то, что уже определено это отношение в модели?(Пользователь может создавать много продуктов, и продукт принадлежит пользователю)

У меня есть веб-сайт, где пользователи могут создавать продукты.Теперь у этих пользователей также есть страница профиля.Я хочу знать, возможно ли иметь его, чтобы, когда пользователь создает продукт, и я щелкаю сам продукт, он показывает, какой пользователь его создал, и когда я щелкаю имя пользователя, он направляет на страницу своего профиля.

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

Для пользователей соответствующий код:

class UsersController < ApplicationController
  def index
    @users = User.all
  end

  def show
    @users = User.find(params[:id])
  end
end

Схема

  create_table "users", force: :cascade do |t|
    t.string   "email"
    t.string   "username"
    t.string   "encrypted_password"
    t.string   "description"
    t.string   "address"
    t.string   "phone_number"
 end

Для продуктов:

class ProductsController < ApplicationController
  def index
    @products = Product.all
  end

  def new
    @products = Product.new
  end

  def create
      params[:products][:user_id] = current_user.id
      @products = products.new(products_params)
  end

  def edit
    @products = Product.find(params[:id])
  end

  def update
    @products = Products.find(params[:id])
    @products.update_attributes!(products_params)
    flash[:notice] = "#{@products.name} has been succesfully updated."
    redirect_to show_my_products_path
  end

  def destroy
    @products = Product.find(params[:id])
    @products.destroy
    flash[:notice] = "Your product '#{@products.name}' has been deleted."
    redirect_to show_my_products_path
  end

  def show
    @products = Product.find(params[:id])
  end

end

Схема

  create_table "products", force: :cascade do |t|
    t.string   "name",                default: "", null: false
    t.string   "description"
    t.string   "quantity"
    t.datetime "created_at",                       null: false
    t.datetime "updated_at",                       null: false
    t.integer  "user_id"
  end

Для страницы шоу продуктов, это по существуотображает информацию о продукте.Я хочу добавить одну строку:

<%= link_to "#{user.username}",  users_show_path_url(user), class: 'link_to'   %>

Где, если вы щелкнете по этой ссылке на странице продукта, которую создал пользователь, она перейдет на страницу его профиля.Тем не менее, я получаю ошибку, когда на странице show.html.erb для продуктов:

undefined method `username' for nil:NilClass

ИЛИ

Couldn't find User with 'id'= .... 

Я думаю, я не слишком уверен, как я могусвязать пользователя, который создал свой продукт, и отобразить его имя пользователя для этого конкретного продукта.Я попытался добавить:

@users = User.all
@users = User.find(params[:id])

К контроллеру продукта шоу.

Кроме того, это модель:

class User < ActiveRecord::Base
  has_many :products
end

class Product < ActiveRecord::Base
  belongs_to :user
end

Я намеренно пропустил некоторыекод и выбрал наиболее подходящий код, но если вам требуется больше кода, пожалуйста, сообщите мне.

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

Ответы [ 4 ]

0 голосов
/ 19 декабря 2018

Я не уверен, что ваша функция создания в контроллере Products работает должным образом.

Во-первых, при вызове Product.new для продукта требуется заглавная буква P. https://apidock.com/rails/v3.2.13/ActiveRecord/Base/new/class

SecondЯ не думаю, что вы правильно связываете пользователя.

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

В зависимости от ваших product_params, потенциально вы можете сделать что-то вроде:

def create
  attributes = product_params.merge(user_id: current_user.id)
  @product = Product.new(attributes)

  if @product.save
    redirect_to show_my_products_path, notice: 'Product was successfully created.'
  else
    render :new
  end
end

В этом случае, поскольку вы не передаете user_id в параметрах, вам не нужно указывать user_id в ваших product_params.

Тогда при правильном просмотре вы сможете вызвать

<%= link_to @product.user.username, users_show_path_url(user), class: 'link_to' %> |

Я также вижу, как вы вызываете Products.find в других методах, где они должны быть единственными.(Потенциально это отдельная проблема) https://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-find

Также рекомендуется называть ваши методы экземпляра единичными, если в индексе есть только один, кроме того, что все они будут @product, а не @products, но это чисто дляудобочитаемость.


Общие советы. Лучше постараться как можно больше защитить приложение, и рельсы позаботятся о вас.

Например, отС нуля я запустил

rails g scaffold user username

rails g scaffold products name user:references

rails db:migrate

У меня нет всех атрибутов, так как это был всего лишь пример, но это сгенерировало весь код, необходимый для того, чтобы все работало как задумано (кроме has_many в моей модели).Это чрезвычайно полезная вещь для изучения:)

0 голосов
/ 18 декабря 2018

Чтобы использовать переменную user, вам нужно присвоить ее, и я не вижу, где это делается в действии show product.

Вместо этого попробуйте получить доступ к пользователю через продукт:

<%= link_to "#{@products.user.username}",  users_show_path_url(@products.user), class: 'link_to' %>

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

0 голосов
/ 18 декабря 2018

Прежде всего, я создам устройство User

rails generate devise User

Затем я создам задание

rails g scaffold Task name:string description:text user:references

Затем я изменю контроллер задач

class TasksController < ApplicationController
  before_action :set_task, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, except: [ :show, :index]
  # GET /tasks
  # GET /tasks.json
  def index
    @tasks = Task.all
  end

  # GET /tasks/1
  # GET /tasks/1.json
  def show
  end

  # GET /tasks/new
  def new
    @task = current_user.tasks.new
  end

  # GET /tasks/1/edit
  def edit
  end

  # POST /tasks
  # POST /tasks.json
  def create
    @task = current_user.tasks.new(task_params)

    respond_to do |format|
      if @task.save
        format.html { redirect_to @task, notice: 'Task was successfully created.' }
        format.json { render :show, status: :created, location: @task }
      else
        format.html { render :new }
        format.json { render json: @task.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /tasks/1
  # PATCH/PUT /tasks/1.json
  def update
    respond_to do |format|
      if @task.update(task_params)
        format.html { redirect_to @task, notice: 'Task was successfully updated.' }
        format.json { render :show, status: :ok, location: @task }
      else
        format.html { render :edit }
        format.json { render json: @task.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /tasks/1
  # DELETE /tasks/1.json
  def destroy
    @task.destroy
    respond_to do |format|
      format.html { redirect_to tasks_url, notice: 'Task was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_task
      @task = Task.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def task_params
      params.require(:task).permit(:name, :description, :user_id)
    end
end

Затем я добавлю новый столбец в таблицу User.

rails generate migration add_username_to_users username:string

Затем я выполню команду миграции

rake db:migrate

Затем я добавлю поле имени пользователя вФорма регистрации # / views / devise / registerations / new.html.erb

<div class="field">
  <%= f.label :username %><br />
  <%= f.text_field :username, autofocus: true, autocomplete: "username" %>
</div>

Затем я разрешу имя пользователя в контроллере devise

class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
  end
end

А затем добавлю проверку дляимя пользователя в # user.rb

  validates :username, uniqueness: true, presence: true

Тогда я добавлю ссылку в модель пользователя

has_many :tasks

Теперь вы можете показать свое имя пользователя с задачей В просмотрах везде

<%= task.user.username %>

Вот рабочий пример Пример связи ассоциации для отображения имени пользователя

0 голосов
/ 12 декабря 2018

Попробуйте:

   <%= link_to user_path(@product.user), title: @product.user.username do %>
     <%= @product.user.username %>
   <% end %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...