#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%>
Спасибо вам за тех, кто протянул руку помощи!