not sure how to use nested routes to model this pattern
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

I'm trying to make the below screenshot work and I'm not sure how to model this pattern using nested routes. The screenshot is of my users#show page.

As a user,
Given I click Attach proof to 1.1.3 and
Given I'm redirected to new_standard_requirement_path
When I fill in the image url on the form and
When I fill out a note on the form
Then I expect to see only that image and note next to 1.1.3. The same for 1.1.2 and 1.1.4, etc.

screenshot 2014-03-04 11 46 46

I’m not entirely sure how to model this pattern. This is how far I've come so far!
https://github.com/akshatpradhan/compliance_chimp/commit/148bc4f78c7b35f3f7a49052be5d8991e5fdbd24

From the thoughtbot workshop videos, it seems this pattern is quite commonly handled with nested routes.

The reason I'm using a nested routes pattern is from this thoughtbot video. Its about 18 mins long but really good and shows how to use "Decks and Cards" in a nested route: https://www.dropbox.com/s/io8jf3r0j3psotl/Rail%20Controller%20and%20Views%2C%20Part%201.mp4

I'll help you modeling the pattern. Some quick questions for when you get up :) User has many Standard(s) has many Requirement(s) is that right? In users#show you want to list all his standards, right ? In the same page you want to list requirements for each user standard, right?
kc00l almost 6 years ago
There's still something I don't understand in the Standard - Requirement - User models relationship. The way your showing standards on the users#show page seems to indicate each standard has a single requirement. Could you clarify the PCI compliance domain for me ? Moreover in the standards table you call "requirement" the standard description, this is a bit confusing. I'll put this on hold until you read my comments, since I think I'm not getting things right.
kc00l almost 6 years ago
I just updated the branch so that pages on user_path(current_user) and root_path look a bit more realistic for the end user. I think that might have confused people. I think what's also confusing is my naming scheme for the models. I think the model Standard makes sense because it maps directly to the 200 PCI Compliant standards that need to be marked as completed. I was thinking Requirement should have the fields image_url, note, and updated_at, but I couldn't think of a better name for the Requirement model. Maybe instead of Requirement, the model should be named Proof?
akshatpradhan almost 6 years ago
Just updated the question entirely with a User Story. If its still confusing, i can make a 2 min video to demonstrate the workflow!
akshatpradhan almost 6 years ago
Ok it is clearer now. I still don't get if you want multiple Proofs/Requirements for a single Standard.
kc00l almost 6 years ago
In the future, a company may need to attach multiple images to prove a requirement has been met, but until someone complains about it (complaint driven development), let's not do multiple Proofs/Requirements for a single Standard. One proof per requirement for now. Btw, it does seem like the model name Requirement is a poor choice. I'm on thesaurus.com and found some possible alternative names. If you think we should go with one of these, I'm very open to changing it: http://thesaurus.com/browse/proof What do you think about Assessment? instead of Requirement? There's also Verification or Proof could be just as good too I guess. Someone once told me that half the battle of being a good developer is coming up with nice names for classes, methods, and variables.
akshatpradhan almost 6 years ago
Proof sounds nice and clearly expresses the concept. I can post my solution now.
kc00l almost 6 years ago
@kc00l and @sguha I was curious about your opinion about whether this should be open sourced or not and what license you think should best fit this. I'd like to turn this into a subscription based SAAS in the future. The target market would be companies trying to become PCI compliant.
akshatpradhan almost 6 years ago
awarded to kc00l

Crowdsource coding tasks.

2 Solutions


Check out the nested resources section here http://edgeguides.rubyonrails.org/routing.html#nested-resources, specifically 2.7.1 and 2.7.2 where they recommend not having more than 1 id in a url. I would therefore change your routes.rb to use the shallow option

resources :standards do
  resources :requirements, :shallow => true
end

The index create and new actions for a Requirement object will be nested under the corresponding Standard but the show update delete and edit actions will be accessed directly through the Requirement

@sguha glad to see you're still around! :) I'll look at the :shallow => true concept on Edge Rails in a couple hours. I made 2 good commits today and I just need to take a small coding break. I'm not sure I can learn anything at this hour, lol.
akshatpradhan almost 6 years ago
Glad to see you're still working on interesting rails projects :). I was unclear on what you meant by "However, I couldn’t seem to get the standard.name, standard.description, and the associated requirement.image_url to show up on users#show." I didn't see references to those methods in the UsersController or the show erb template.
sguha almost 6 years ago
@sguha references to standard.name, standard.description and requirement.image_url is pseudo code. You're right that its not in the users#show on the manage_requirements branch. However, the code I TRIED to write up is in the setup_associations branch https://github.com/akshatpradhan/compliance_chimp/compare/setup_associations#diff-593976b4bf314aaa86c2c172e5c1f26dR3. This code is clearly not correct because its in requirements#show and not users#show, but this is the wall I came up against. There's about 200 PCI standards that all people must complete before they are considered PCI Compliant. So I think that implies Standard belongs_to :users and User has_many :requirements I feel like I didn't answer your question very well...would you be able to rephrase it?
akshatpradhan almost 6 years ago
I just wanted to know what specific code you wanted to get working or if you just wanted help setting up the appropriate nested URLs
sguha almost 6 years ago
ok, let me rewind and break this down so that I'm not lost. I git push forced a new commit with a more concrete failure. The failure I'm seeing is in the commit message. How do I get past the failure in the commit message? https://github.com/akshatpradhan/compliance_chimp/commit/4950a5ce318b693bea407674bae56f2cb2172846
akshatpradhan almost 6 years ago
Ok, I got a little bit further. I just git push forced a new commit: https://github.com/akshatpradhan/compliance_chimp/commit/087f27d81a9480ec10692f12c42e2f4b201f2ef1 I put the error I'm seeing in the commit message. Its the same routing error. But I added a Requirements model and instantiated some objects in the RequirementsController. Also improved the test case to mimic a User clicking "Attach Screenshot" which should go to new_standard_requirement_path
akshatpradhan almost 6 years ago
I think you had a typo, should be standard not @standard. I made a pull request https://github.com/akshatpradhan/compliance_chimp/pull/8
sguha almost 6 years ago
@sguha Thank you, it wasn't a typo, it was my misunderstanding, but now I know the difference between standard and @standard! Would you be able to get me over this next hurdle? After clicking submit, I'm trying to get the image_url to show up on users#show, but I keep getting this error. https://github.com/akshatpradhan/compliance_chimp/commit/08dbf2d92b8f71911bbc75668cc70fe5b52bf6fa
akshatpradhan almost 6 years ago
added a comment to the pull request!
akshatpradhan almost 6 years ago
Just updated the question entirely with a User Story. If its still confusing, i can make a 2 min video to demonstrate the workflow!
akshatpradhan almost 6 years ago
I added a couple more commits to my pull request so that the users#show action renders like the screenshot you provided. You still need to add the edit and update actions and templates for the RequirementsController, but that should be fairly straightforward. Let me know if you need help though!
sguha almost 6 years ago
Winning solution
Tipped

This is my pull request for this solution : https://github.com/akshatpradhan/compliance_chimp/pull/10

Some of the changes I made should sound familiar since we've already done similar stuff in LendingRound.
I added the User-Standard association and changed the show action in UsersController by setting @standards = @user.standards. This way only standards belonging to user are shown.

As for the standard requirements showing in the view I saw you had already done most of the work by looping through standard.requirements (actually I didn't see your last commit and I had to merge and fix conflicts..). I added a condition for showing standard.requirements only when there are any.

<% if standard.requirements.any? %>
  <ul>
    <% standard.requirements.each do |requirement| %>
      <li><%= requirement.image_url %></li>
    <% end %>
  </ul>
<% end %>

In order for specs to pass with the new associations I had to create a user factory and force the user belonging to the standard factories.

feature 'Manage requirements' do
  given!(:user) {create(:user)}

  background do
    OmniAuth.config.test_mode = true
    OmniAuth.config.mock_auth[:github] = {
      'uid'  => user.uid,
      'provider' => user.provider,
      'info' => {
        'name' => user.name,
        'email' => user.email
      }
    }
  end

  scenario 'user views all standards' do
    (1..2).each do |n|
      create(:standard, name: "1.1.#{n}", user: user)
    end
  ...
  end

  scenario 'user adds a new requirement screenshot' do
    create(:standard, name: "1.1.1", user: user)
  ...     
end 
hey quick question, if I changed the Standard model to has_one :requirement, what would the code on users#show look like. I tried to change users#show to <%= standard.requirement.image_url %> but I get a undefined method image_url for nil:NilClass. However, a .inspect gives me this: #<Requirement _id: 531638a25cf4e8a6ba000003, image_url: "http://www.imgur.com/1.1.1.png", standard_id: "531638885cf4e8beee000001">,
akshatpradhan almost 6 years ago
You need to check for standard.requirement existence, e.g. <℅= standard.requirement.image_url if standard.requirement %>, I actually would create a method on the standard model to return a requirement image_url if the requirement exist.
kc00l almost 6 years ago
argh! when I change @requirement = @standard.requirement.new, I keep getting an error similar to this: http://stackoverflow.com/questions/9170245/undefined-method-new-for-nilnilclass-whats-wrong-with-has-one-nested-assoc I've been googling how to get nested routes with a has_one relationship for Standard and Requirement and I keep getting this undefined method new for nil class just like the above. Can't seem to figure this out!
akshatpradhan almost 6 years ago
for 1-1 you need to use @standard.build_requirement :-) See here: http://guides.rubyonrails.org/association_basics.html#has-one-association-reference (4.2.1)
kc00l almost 6 years ago
I was JUST on it, lol.
akshatpradhan almost 6 years ago
View Timeline