0

I'm in the process of refactoring some code. I'm trying to use arrays in my view as part of a for loop that makes columns in a table.

I have defined the arrays in my controller:

subjects_controller.rb

def index
    ...
    @CRFS_TO_VIEW = [Baseline, TreatmentCompletion]
    @CRF_PATH = {Baseline => 'baseline_path', TreatmentCompletion => tc_path}
end

So my goal; as the function iterates over @CRFS_TO_VIEW, the correct path is selected from @CRF_PATH and appended to the link_to function.

indext.html.erb

<% @CRFS_TO_VIEW.each do |crf| %>
  <% path = @CRF_PATH[crf] %>
  <%= link_to "edit", path(crf.where(subject_id: sub.subject_id).first %>
<% end %>

I also tried :

<%= link_to "edit", @CRF_PATH[crf](crf.where(subject_id: sub.subject_id).first %>

Which didn't work. I feel I must be getting close, any help or insight would be greatly appreciated.

Thanks.

3
  • in the @CRFS_TO_VIEW array, shouldn't the elements be strings? like @CRFS_TO_VIEW = ['Baseline', 'TreatementCompletion']. Same with @CRF_PATH. Commented Sep 8, 2016 at 18:46
  • That may be the case, I'll try it out for sure. But before that, saving @CRF_PATH[crf] to path isn't working. Path isn't identified. Perhaps I can't declare a variable in the view? Commented Sep 8, 2016 at 18:52
  • So @CRFS_TO_VIEW doesn't work because the items aren't strings. They are references to controllers. Such that Baseline.create(id) should work. Commented Sep 8, 2016 at 18:55

1 Answer 1

2

A few things:

a. You should save yourself some time and loop through the dictionary instead of the array:

<% @CRF_PATH.each do |crf, path| %>
...
<% end %>

b. You are getting a string from the loop - you can invoke the equivalent method with send:

<%= send(path, ...) %>

c. You can simplify your retrieval of the objects using:

crf.find_by(subject_id: sub.subject_id)

That said - this seems like a pretty bad way of doing things. I'd recommend instead adding a view helper:

def crf_path(crf)
  case crf
  when Baseline then baseline_path(crf)
  ...
end

With something like this you could use (notice changed the find_by to find_by! for safety as well):

<% @CRFS_TO_VIEW.each do |crf| %>
  <%= link_to "edit", crf_path(crf.find_by!(subject_id: sub.subject_id) %>
<% end %>

Finally instance variables should NOT be named upper case. If you want to use a constant define it as a constant (otherwise use lower case names).

Sign up to request clarification or add additional context in comments.

3 Comments

This is incredibly helpful. I didn't even think I could use view helpers in that way. I think this is the answer I was looking for, I spend some time with this and maybe ask you a question or two. Thanks so much.
Are these view helpers for rails 4.0 and above only? Or better question, where do I put the helper?
@IanEllis You can put them under app/helpers/application_helper.rb.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.