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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.