2016-06-15 6 views
0

Это похоже на общую, но сложную проблему, но я не смог найти подсказки о том, как решить эту проблему в Интернете. У меня есть 2 таблицы, userprofile и программы. Каждый userprofile has_many :programs и programs belongs_to :userprofile.Рельсы, как получить доступ к таблице принадлежит без использования итерации

Userprofile.rb

class Userprofile < ActiveRecord::Base 
    attr_accessible :user_id, :programs_attributes 
    has_many :programs 

    accepts_nested_attributes_for :programs 

Program.rb

class Program < ActiveRecord::Base 
    attr_accessible :userprofile_id, :program_name, :program_role, :program_year 

    belongs_to :userprofile 
end 

Моя проблема, я хочу, чтобы показать заголовок ("Программы"), только если userprofile.programs не пусто, и если каждый из program_name, program_role и program_year не пуст.

Когда я использую итератор, я могу проверить на program_name, program_role, program_year. Но заголовок «Программа» печатает несколько раз (в зависимости от номеров программ, которые пользователь полностью заполнил).

<% @userprofile.programs.each do |program| %> 
    <% if program.blank? || program.program_name.blank? || program.program_role.blank? || program.program_year.blank? %> 
    <% else %> 
    <h3>Program </h3> <br /> 
    <%= program.program_name %><br /> 
    <%= program.program_role %><br /> 
    <%= program.program_year %> 
    <% end %> 
<% end %> 

Но когда я переместить заголовок из петли, я не знаю, как сделать проверку:

<% if @userprofile.programs.blank? || @userprofile.programs.program_name.blank? %> 
<% else %> 
    <h3>Program </h3> <br /> 
    <% @userprofile.programs.each do |program| %> 

    <%= program.program_name %><br /> 
    <%= program.program_role %><br /> 
    <%= program.program_year %> 

    <% end %> 
<% end %> 

Это приведет к ошибке undefined method 'program_name'. Я подумал о том, чтобы взять заголовок из итерации и каким-то образом получить доступ к program_name, program_role, program_year решит проблему, но я не уверен, как правильно ее достичь.

Я также попытался отображение (how to access fields in belongs_to association in rails)

<%= @program_names = @userprofile.programs.map(&:program_name) %> 
<%= @program_years = @userprofile.programs.map(&:program_year) %> 
<%= @program_roles = @userprofile.programs.map(&:program_role) %> 

    <% if @userprofile.programs.blank? || @program_names.empty? || @program_years.empty? || @program_roles.blank? %> 
    <% else %> 

     <h3>Program </h3> <br /> 

     <% @userprofile.programs.each do |program| %> 

     <% if program.program_name.blank? %> 
     <% else %> 

      <%= program.program_name %><br /> 
      <%= program.program_role %><br /> 
      <%= program.program_year %> 
     <% end %> 
     <% end %> 
    <% end %> 

Который, казалось, работали, за исключением того, когда все массивы, например: [ "", "", ""] или [ноль, ноль, ноль]. Заголовок «Программа» все еще отображается, когда он должен быть скрыт.

Любые предложения помогут. Спасибо!

ответ

1

Для запроса, юбилеи, вы должны сделать:

@userprofile.programs.where.not(program_name: nil, program_role: nil, program_year: nil) 

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

#models/program.rb 
... 
def displayable? 
    program_name.present? && program_role.present? && program_year.present? 
end 
... 

Тогда, по вашему мнению, вы должны быть в состоянии сделать

<% programs.each do |program| %> 
    <% if program.displayable? %> 
     <%= program.program_name %><br /> 
     <%= program.program_role %><br /> 
     <%= program.program_year %> 
    <% end %> 
<% end %> 

UPDATE

Как @ Éric-côté отметил, вы должны быть в состоянии сделать:

scope :displayable_programs, -> { where.not(program_name: nil, program_role: nil, program_year: nil) } 

При таком подходе, на ваш взгляд, вы бы сделали:

<% programs = @userprofile.programs.displayable_programs %> 
<% if programs.exists? %> 
    <h3>Program </h3> <br /> 
    <% programs.each do |program| %> 
     <% if program.displayable? %> 
      <%= program.program_name %><br /> 
      <%= program.program_role %><br /> 
      <%= program.program_year %> 
     <% end %> 
    <% end %> 
<% end %> 

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

<% program_shown = false %> 
<% @userprofile.programs.each do |program| %> 
    <% if program.blank? || program.program_name.blank? || program.program_role.blank? || program.program_year.blank? %> 
    <% else %> 
    <% unless program_shown %> 
     <h3>Program </h3> <br /> 
    <% program_shown = true %> 
    <% end %> 
    <%= program.program_name %><br /> 
    <%= program.program_role %><br /> 
    <%= program.program_year %> 
    <% end %> 
<% end %> 
+1

Вы также могли бы иметь отношения с областью, как это: 'has_many: displayable_programs, -> {где ,not (имя_программы: nil, program_role: nil, program_year: nil)} '. Затем просто используйте '@ userprofile.displayable_programs'. –

+0

Метод 'displayable? 'Не работал для меня. Но я не уверен, что это решит проблему отображения текстового заголовка «Программа», потому что все еще существует цикл для проверки пустых строк. Поэтому, если я поместил текст внутри цикла, он просто напечатает его х раз. – teresa

+0

Я сделал обновление для ответа, чтобы показать, как вы могли бы включить это, а также предоставили логику, которую вы могли бы использовать в своем предыдущем подходе. – oreoluwa