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

#ruby-on-rails #ruby #join #crud

Вопрос:

Я пытаюсь создать приложение, в котором пользователи могут публиковать задания, а другие пользователи могут принимать эти задания, и чтобы маршрут был «завершен» после нажатия кнопки «Принять задание». Я создал объединенную таблицу для размещения нескольких пользователей-респондентов. Проблема в том, что мои согласия не сохраняются. Вот мои модели:

 class User < ApplicationRecord
    has_secure_password
    validates :username, presence: true
    validates :email, presence: true
    validates :email, uniqueness: true 
    has_many :acceptances
    has_many :job_requests, :class_name => "Job", :foreign_key => "requestor_user_id"
    has_many :job_responses, :class_name => "Job", :foreign_key => "responder_user_id"
end
 
 class Job < ApplicationRecord
    has_many :acceptances
    belongs_to :requestor_user, :class_name => "User"
    has_many :responder_user, :class_name => "User", through: :acceptances
end
 
 class Acceptance < ApplicationRecord
    belongs_to :user
    belongs_to :job
end
 

И это метод обновления, который берется со страницы «Показать», на которой находится задание «Принять».

  def update
        @job = Job.find(params[:id])
        @acceptance = Acceptance.create(job_id: @job.id, responder_id: @current_user.id)
        @job.acceptances << @acceptance
        if @job.save
            redirect_to jobs_path
        else
            render :show
        end
    end
 

Любая помощь/ совет будут очень признательны!

Комментарии:

1. Моделирование здесь действительно вызывает недоумение. Я не понимаю, почему модель задания также служит записью запроса пользователя на выполнение этой работы или чего-то еще, что должно быть в вашем домене. Я думаю, что вам действительно нужно сначала поработать над моделью домена (таблицами), а затем удалить эту логику JobsController#update и создать совершенно отдельную конечную точку для приема предложений о работе. Такое чувство, что вы включаетесь как сумасшедший, и вы полностью упустили тот факт Acceptance.create(job_id: @job.id, responder_id: @current_user.id) , что создается дополнительный путь кода, с которым необходимо разобраться.

2. Его действительно один путь кода ко многим и нарушает SRP, так как у JobsController внезапно появилось два задания. Будьте осторожны, относясь к таблицам соединений просто как к сантехнике — постарайтесь думать о них как о сущностях в вашем домене и создавайте надежные маршруты для их создания, обновления и уничтожения. Я бы рекомендовал вам ознакомиться с вложенными ресурсами .

3. Спасибо тебе за это, Макс! Если хотите, я ответил на свой собственный вопрос и добавил некоторую документацию для этого исправления и какова была моя общая цель.

Ответ №1:

Я бы предложил вот это..

   def update
    @job = Job.find(params[:id])
    @acceptance = @job.acceptances.new(job_id: @job.id, user: @current_user)
    if @acceptance.save
        redirect_to jobs_path
    else
        render :show
    end
  end
 

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

Комментарии:

1. Я закончил тем, что изменил свои отношения в рамках своих моделей. В любом случае, спасибо вам за ваш вклад!

Ответ №2:

Я нашел решение для тех, кто ломает голову над чем-то подобным. https://www.theodinproject.com/paths/full-stack-ruby-on-rails/courses/ruby-on-rails/lessons/active-record-associations . Это отличная ссылка для расширения ваших знаний, размещенная в проекте odin. В принципе, я расположил свои модели следующим образом:(работа)

  belongs_to :requestor_user, :class_name => "User"
    has_many :acceptances, foreign_key: :job_response_id
    has_many :responder_users, through: :acceptances, source: :responder
 

(пользователь)

     has_many :acceptances, foreign_key: :responder_id
    has_many :job_requests, :class_name => "Job", :foreign_key => "requestor_user_id"
    has_many :job_responses, through: :acceptances
 

(принятие)

     belongs_to :responder, class_name: "User"
    belongs_to :job_response, class_name: "Job"
 

По сути, цель здесь состояла в том, чтобы выяснить, как разделить две разные группы одной и той же модели(в примере User amp; job). Оттуда я смог разместить принятые заявки в таблице соединений. Оттуда я смог создать ответ, а также ответчика для конкретной работы в моем маршруте обновления.:

 def update
        @job = Job.find(params[:id])
        @current_user.job_responses << @job
        @job.responder_users << @current_user
        if @job.save
            redirect_to jobs_path
        else
            render :show
        end
    end
 

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

 <%if @acceptance%>
<h2>Completed!</h2>
<%else%>
<%= form_for(@job) do |f| %>
    <%= f.submit "Accept Job" %>
<% end %>
<%end%>
 

Спасибо вам за тех, кто протянул руку помощи!