Перебор имен столбцов с переменной

#ruby-on-rails #ruby #ruby-on-rails-3

#ruby-on-rails #ruby #ruby-on-rails-3

Вопрос:

У меня есть метод model, который создает отчет для приложения-вопросника. Каждый столбец в таблице представляет отдельный вопрос, и каждая строка является интервьюируемым. Он использует метод column_names для создания массива идентификаторов вопросов, а затем добавляет соответствующие ответы.

 def self.import_answers(params)

@members = Member.where(:questionnaire_id => params[:questionnaire])
@columns = Report.column_names
@members.each do |member|
  @report = Report.find_by_membership_number(member.membership_number)
  @responses = Response.where(:member_id => member.id)
  @columns.each do |column|
    question = column.to_s.gsub("q", "").to_i
    @response = @responses.where(:question_id => question).first
    unless @response.nil?
      @report.column = @response.response_id
      @report.save
    end
  end
end
  

завершение

Этот метод прерывается в строке @report.column.

Я думаю, это может быть потому, что метод column_names возвращает массив строк, вот так…

 ["q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10"]
  

Это означает, что строка @report.column повторяется как

 @report."q1"
  

в отличие от…

 @report.q1
  

который работает.

Я могу ошибаться на этот счет! Но в любом случае, я изо всех сил пытаюсь понять, как я могу заставить это работать, любая помощь была бы высоко оценена!

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

1. Вы не показываете, где @report определяется. Кроме того, можете ли вы добавить точную ошибку, которая возникает? Просто сообщать, что он прерывается, слишком двусмысленно. Какого результата вы ожидаете? Вы ожидаете, что @report это будет массив интервьюируемых, содержащий массив вопросов и ответов?

2. В таблице reports создается строка для каждого элемента. @report ссылается на строку (элемент) в таблице. Я обновил свой вопрос, чтобы показать полный метод.

Ответ №1:

Вы можете использовать send("#{atr}=") для динамической установки атрибута. После просмотра вашего кода, возможно, вам будет лучше использовать, update_attribute поскольку он выполняет операции set и save за один вызов.

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

 class Report < ActiveRecord::Base
  # extract the question id from the column
  def self.column_question_id(name)
    name[1..-1].to_i
  end
end
  

Теперь ваш код может быть записан как:

 Report.column_names do |column|
  @response = @responses.find_by_question_id(Report.column_question_id(column))  
  @report.update_attribute(column, @response.response_id) if @response.present?
end
  

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

1. Да! Это сработало отлично. Хотя для написания update_attribute действительно требовалась дополнительная буква T, я не буду держать на вас зла за это. Огромное спасибо, ОТМЕТЬТЕ!

Ответ №2:

 @report.send(column.to_sym) = @response.response_id
  

Ответ №3:

@report.send("#{column}=".to_sym, @response.response_id)

Вы можете получить больше информации здесь.