Updating all with a dictionary in Rails - ruby-on-rails

I have a small CMS-like program that has multiple pages that act like blog posts. Each page has content, and a position integer that identifies in what order they will appear on the page.
On my admin side, I have a draggable list of pages that I can reorder similar to how wordpress orders plugins. The page works as functions, and assigns the value of the dragged position to each page correctly. However, since all sortable pages have their own form, I cannot submit them all at once - only one at a time.
As an example, my code looks like this currently:
<div class="sortable">
<% #pages.each do |page| %>
<div class="dragBox">
<%= form_for(page) do |f| %>
<%= f.number_field :position, class: 'inPosition' %>
<% end %>
</div>
<% end %>
</div>
Because I can get every page_id tied to its new position, is it possible to submit those values in a new hash to get updated all at once in the controller? How would I go about doing this? Is there a better or easier way to do this? Thanks.

Related

How to display music in a category when a category is clicked (without a page refresh) in Ruby on Rails?

I am building a website for a music database.
I would like to display categories like classical and hip hop first; when the user clicks on a category, I would like to display all the tracks names in that category (I would like to do this without a page refresh). I would also need to support pagination of this list displaying 10 items in one page (and I need to display buttons for display, edit, delete alongside each track in this list)
How can I accomplish this? Does bootstrap provide components that support this kind of implementation?
(If I could do this with a page refresh, I have done this before and I would know how to do it. But I am not sure how to do this without a page refresh)
On views/categories/index.html.erb:
<% #categories.each do |category| %>
<%= link_to category_path(category), :remote => true do %>
<%= category.name %>
<% end %>
<div class="category_<%= category.id %>">
</div>
<% end %>
Then create a partial views/categories/_show.html.erb (here you can insert a table or a structure with bootstrap row and columns):
<% #category.tracks.each do |track| %>
<%= track.name %>
... and you can add here delete and edit actions
<% end %>
Then create views/categories/show.js.erb:
$(".category_<%= #category.id %>").html("<%= escape_javascript(render("show")) %>");
Fyi what you are trying to do has nothing to do with bootstrap, unless you wanted for instance display tracks on a bootstrap modal.
Here is a poor man's bootstrap example I whipped up: when you click on the Track Category example, the table should expand. (You must have bootstrap v4 set up for this to work) and you must have a track_table partial as well - you can use the same partial for the two different tables that you want:
<div class="track-group">
<div class="track track-default">
<div class="track-heading">
<h4 class="track-title">
<p data-toggle="collapse" href="#collapse1"> Track Category (Click to Expand)</p>
</h4>
</div>
<div id="collapse1" class="track-collapse collapse">
<div class="track-body">
<%= render 'track-table' %>
</div>
<div class="track-footer">
</div>
</div>
</div>
</div>
Here's how it looks with an existing app on my computer:

Ruby on Rails: 'don't show on all these pages' condition

I am new to Ruby on Rails and am having a difficult time figuring out how to not show a div on more than one page. Currently, I've only been able to make the following work for a single page:
<% if signed_in? %>
<% unless current_page?(account_setup_path) %>
<!--job seeker options-->
<% if current_user.job_seeker? %>
test
<% end %>
<!--end job seeker options-->
<!--employer options-->
<% if current_user.employer? %>
<% end %>
<!--end employer options-->
<% end %>
<% end %>
Any help will be much appreciated! Thanks in advance!
Since you want a div to not be shown on multiple pages you have several options. First, if the div is only meant to be shown on pages with a certain controller you'll want to move that div into a partial and reference it from all the associated views. If you want in only shown on one page you should put it in the view directly. If you need it shown on several different pages accross your app. you can simply check if the controller in your params hash matches. For example:
#I want this div shown on any pages handled by my `Admins` and `Users` controllers.
<% if params[:controller] == 'admins' || params[:controller] == 'users' %>
div here
<% end %>
This will add overhead to maintenance so you should think hard whether this div should be in a partial, in a specific view, or in the layout/application file etc.

Rails partial for collection, only display certain things for first element

I have a collection of elements I'm rendering in a partial, but I only want to display a certain element with the very first element. My specific instance is displaying email addresses but I only want the email icon to show once next to the first instance (similar to how the Android Contacts app does).
I have a very "hacky" solution that uses instance variables in the view, which is not a good practice. But I'm struggling to find a cleaner way to implement what I want.
The controller:
#email_addresses = EmailAddress.order(:primary) # primary is a boolean value
The partial:
# views/email_addresses/_email_address.html.erb
<div class="email-address">
<% unless #email_icon_displayed
<% #email_icon_displayed = true %>
<div class="email-address-icon">
<span class="icon email"></span>
</div>
<% end %>
<div class="email-address-value">
<%= email_address.value %>
</div>
</div>
Calling partial in view:
<%= render partial: "email_addresses/email_address", collection: #email_addresses %>
This works properly and only displays the email icon for the first element, but instance variables in the view seems like a bad idea.
This may be a little late, but I had the same goal and I achieved it by using a "hidden" counter variable in Rails partial collections.
I called my partial collection like this:
<%= render partial: "questions/possible_answer",
collection: question.possible_answers, as: 'value' %>
And inside my partial I can access the variable value_counter, which increments for each partial. So to run something with the first element only, I did it like this:
if value_counter == 0
#do something
end
I think your case you would need to access it like this: email_address_counter
Found this solution here: https://coderwall.com/p/t0no0g/render-partial-with-collection-has-hidden-index

How to access specific object fields?

I am building a basic bare bones social media app right now.
I have a user class and a status class.
For each status, there is a "creater" (a user object) and a "subject" (a user object that the status is about). I was able to create tags by using the acts_as_taggable_on gem. What ends up happening is when a user goes to create a post, he/she can select another user from a dropdown menu. The chosen user's id attribute is then stored.
Now I am trying to link to the chosen User's profile. This is my code for show statuses on a profile page.
<% if #statuses %>
<% #statuses.each do |status| %>
<div class="well">
<%= status.content %>
<br></br>
#link to user who's associated with the tagId
<%= link_to User.find(status.tag_list).profile_name, user_profile_path(User.find(status.tag_list).profile_name) %>
<hr />
<%= link_to time_ago_in_words(status.created_at), status_path(status) %> ago
</div>
<% end %>
<% end%>
this is the line where the above code breaks
<%= link_to User.find(status.tag_list).profile_name, user_profile_path(User.find(status.tag_list).profile_name) %>
Can anyone help me out with this?
Not surprised this line is failing:
<%= link_to User.find(status.tag_list).profile_name, user_profile_path(User.find(status.tag_list).profile_name) %>
A couple points:
It's a little cleaner to separate it onto multiple lines
I suspect your problem is because you're passing a profile_name to user_profile_path instead of an id, though I can't be certain without seeing your routes.
Try the following:
<% profile_user = User.find(status.tag_list) %>
<%= link_to profile_user.profile_name, user_profile_path(profile_user.id) %>

How to create more than one index page in Ruby on Rails

I have two different plans (plan with an ID of 1 and plan with an ID of 2). I've created a partial for each to show on the home page based on which plan the user is logged in as. I would like to create two different index pages for each plan to be directed to.
Plan ID 1 users need to be directed to an index of users with a plan ID of 2, and plan ID 2 users need to be directed to an index of users with a plan ID of 1. Here's the part of the code that controls this feature. How can I create an index feature which sends plan ID 1 and plan ID 2 user to different pages after click on the relative partial?
pages/home.html.erb
<div class="col-md-6">
<% if current_user.plan.name == "mentor" %>
<%= render partial: "pages/mentor" %>
<% else %>
<%= render partial: "pages/mentee" %>
<% end %>
</div>
pages/_mentee.html.erb
<div class="well">
<h2 class="text-center">Mentor Community</h2>
<h4 class='text-center'>Get the support you need.</h4>
<br><%= link_to "Find a Mentor", "#", class: 'btn btn-default btn-lg btn-block' %>
</div>
pages/_mentor.html.erb
<div class="well">
<h2 class="text-center">Mentee Com</h2>
<h4 class='text-center'>Give the support that's needed.</h4>
<br><%= link_to "Find a Mentee", "#", class: 'btn btn-default btn-lg btn-block' %>
</div>
Do this:
#config/routes.rb
root "pages#home"
resources :plans, only: :show #-> url.com/plans/1
#app/controllers/plans_controller.rb
class PlansController < ApplicationController
def show
#plan = Plan.find params[:id]
end
end
#app/views/plans/show.html.erb
<% #plan.users.each do |user| %>
<%= user.name %>
<% end %>
after click on the relative partial
You could send users to the specific plan page by using the following:
#app/views/pages/home.html.erb
<% #plans.each do |plan| %>
<%= link_to plan.id, plan %>
<% end %>
There is so much more you need to consider, but for now, the above should help you get an understanding on the overall structure.
Let me explain a little on how you need to adapt your thinking (this might seem off topic, but will help you profusely, I guarantee it)...
The above is how Rails is meant to work -- it takes a request from the user, matches it to a controller action, and then populates it with model data.
The correct way for Rails to work is with something called object orientated programming - each time you initiate an action / request, it has to invoke & manipulate objects of data.
Whilst this may seem complicated, the sooner you get your head around it, the quicker you'll be able to make much more intricate rails applications.
--
Your question implies that you've not considered the full potential of a data-driven rails application.
Not that it matters, but if you changed your approach so that you got rid of pages and instead had plans with users, you'd be able to have as many plans as you required.
That is the correct way to think about programming (to make a system, not just a quick fix), which you can then use to expand the functionality as you need.
A good way to remove the conditional would be using the plan name to find the partial. It would be something like this
<div class="col-md-6">
<%= render partial: "pages/#{current_user.plan.name}" %>
</div>
But you need to make sure that each plan has its correct partial file. Otherwise you'll get a rendering error, because the partial isn't found.

Resources