Исключение для контроллера действий: неопределенный метод `слияние 'для xxx: String - PullRequest
0 голосов
/ 08 января 2019

Я делаю простой Reddit-подобный сайт. Я пытаюсь добавить кнопку в сообщения. Я создаю report модель, используя button_to, я пытаюсь отправить данные на report controller, чтобы создать ее, но я получил NoMethodError in ReportsController#create undefined method merge' for "post_id":String

модель / report.rb

class Report < ApplicationRecord
  belongs_to :reporting_user, class_name: 'Author'
  has_one :post
end

report_controller.rb

class ReportsController < ApplicationController
  def create
    report = Report.new(report_params)

    flash[:notice] = if report.save
                       'Raported'
                     else
                       report.errors.full_messages.join('. ')
                     end
  end

  def report_params
    params.require(:post).merge(reporting_user: current_author.id)
  end

end

и видимая кнопка

= button_to "Report", reports_path, method: :post, params: {post: post}

В чем причина этой проблемы?

редактирование:

Титулы

=> <ActionController::Parameters {"authenticity_token"=>"sX0DQfM0rp97q8i16LGZfXPoSJNx15Hk4mmP35uFVh52bzVa30ei/Bxk/Bm40gnFmd2NvFEqj+Wze8ted66kig==", "post"=>"1", "controller"=>"reports", "action"=>"create"} permitted: false>

Ответы [ 3 ]

0 голосов
/ 08 января 2019

Проблема, кажется, в report_params. Когда вы вызываете params.require(:post), он выбирает: post from params -> result - string. И вы звоните merge по этой строке.

Я бы рекомендовал изменить вид:

= button_to "Report", reports_path, method: :post, params: { report: { post_id: post} }

затем в контроллере:

def report_params
  params.require(:report).permit(:post_id).merge(reporting_user_id: current_author.id)
end

Обратите внимание, что я также изменил наименование в соответствии с соглашениями: model_id для id модели, модели или самой модели.

0 голосов
/ 08 января 2019

Для начала вы хотите использовать belongs_to, а не has_one.

class Report < ApplicationRecord
  belongs_to :reporting_user, class_name: 'Author'
  belongs_to :post
end

Это правильно помещает столбец внешнего ключа post_id в reports. Использование has_one помещает столбец fk в posts, который не будет работать.

Как правило, лучшим решением было бы создание отчетов во вложенном ресурсе :

# /config/routes.rb
resources :posts do
  resources :reports, only: [:create]
end

# app/controller/reports_controller.rb
class ReportsController
  before_action :set_post

  # POST /posts/:post_id/reports
  def create
    @report = @post.reports.new(reporting_user: current_author)
    if @report.save
      flash[:notice] = 'Reported'
    else
      flash[:notice] = report.errors.full_messages.join('. ')
    end
    redirect_to @post
  end

  private

  def set_post 
    @post = Post.find(params[:post_id])
  end
end

Это позволяет упростить кнопку до:

= button_to "Report", post_reports_path(post), method: :post

Поскольку post_id является частью пути, нам не нужно отправлять дополнительные параметры.

Если вы хотите разрешить пользователю передавать дополнительную информацию через форму в будущем, лучшим способом создания / обновления ресурсов с параметрами и данными сеанса является передача блока:

@report = @post.reports.new(report_params) do |r|
  r.reporting_user = current_user
end
0 голосов
/ 08 января 2019

ActionController :: Parameters # require возвращает значение требуемого ключа в параметрах. Обычно это будет объект, переданный обратно из формы. В этот пример require вернет {name: "Francesco", age: 22, role: "admin"} и слияние будет работать.

Ваше представление отправляет обратно параметры, которые Rails форматирует в {post: 'string'}. Нам нужно увидеть ваш код просмотра, чтобы определить, что именно нужно изменить.

Обновление: из нового опубликованного кода мы видим, что отправленный обратно параметр равен "post"=>"1". Обычно мы ожидаем post: {id: 1, ...}.

Обновление: для кнопки в представлении потребуется обновить ключ params до некоторого значения params: {post: {id: post.id}} РЕДАКТИРОВАТЬ: Я согласен, что params: {report: { post_id: post}} является лучшим форматом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...