View Rails record Associations in modal - ruby-on-rails

In my Rails app I have 3 models Kid, Classroom, and Teacher. Basically, I have a table in my view which lists all the classrooms, when I click on a button I want a modal to pop up that lists the teachers and students assigned to that classroom, as there is an association where a Classroom has_many Teachers and has_many Kids. I have the code ready for the modal, I have copied it below, however I am having a difficult time scoping a specific classroom object to the modal. All help is appreciated!
<div class="modal fade" id="showClassModal" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 id="showClassroomHeader"></h4>
</div>
<div class="modal-body">
<h4>Teachers Assigned</h4>
<ol>
<% #classroom.teachers.each do |teacher| %>
<li><%= teacher.first_name %> <%= teacher.last_name %></li>
<% end %>
</ol>
<br>
<h4>Students</h4>
<ol>
<% #classroom.kids.each do |kid| %>
<li><%= kid.first_name %> <%= kid.last_name %></li>
<% end %>
</ol>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<% if current_user.admin? %>
<button class="btn btn-warning" id="editClassroomBtn">Edit</button>
<% end %>
</div>
</div>
</div>
EDIT:
Classroom controller:
class ClassroomsController < ApplicationController
before_action :set_classroom, only: [:show, :edit, :update, :destroy]
# GET /classrooms
# GET /classrooms.json
def index
#user ||= current_user
if current_user.admin?
#classrooms = Classroom.all
else
#classrooms = #user.classrooms.all
end
end
# GET /classrooms/1
# GET /classrooms/1.json
def show
classroom = Classroom.find(params[:id])
render :text => classroom.class_desc
end
# GET /classrooms/new
def new
#classroom = Classroom.new
end
# GET /classrooms/1/edit
def edit
end
# POST /classrooms
# POST /classrooms.json
def create
#classroom = Classroom.new(classroom_params)
classroom.user = current_user
respond_to do |format|
if #classroom.save
format.html { redirect_to root_url, notice: 'Classroom was successfully created.' }
format.json { render :show, status: :created, location: #classroom }
else
format.html { render :new }
format.json { render json: #classroom.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /classrooms/1
# PATCH/PUT /classrooms/1.json
def update
respond_to do |format|
if #classroom.update(classroom_params)
format.html { redirect_to root_url, notice: 'Classroom was successfully updated.' }
format.json { render :show, status: :ok, location: #classroom }
else
format.html { render :edit }
format.json { render json: #classroom.errors, status: :unprocessable_entity }
end
end
end
# DELETE /classrooms/1
# DELETE /classrooms/1.json
def destroy
#classroom.destroy
respond_to do |format|
format.html { redirect_to classrooms_url, notice: 'Classroom was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_classroom
#classroom = Classroom.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def classroom_params
params.require(:classroom).permit(:class_name, :class_desc, :capacity, :start_range, :end_range)
end
end
Routes.rb:
Rails.application.routes.draw do
resources :rationales
resources :teachers
resources :classrooms
resources :kids
devise_for :users, :skip => [:sessions]
as :user do
get 'login' => "devise/sessions#new", :as => :new_user_session
post 'login' => 'devise/sessions#create', :as => :user_session
delete 'logout' => 'devise/sessions#destroy', :as => :destroy_user_session
end
root :to => 'kids#index'
resources :kids do
get 'discharge', on: :member
end
resources :kids do
get 'restore', on: :member
end
end

As mentioned in the comments section above, adding the modal inside <% #classrooms.each do |classroom| %> did the trick!

Related

How to get value from other class in Rails

I'm not sure if I am phrasing this question correctly. I am using the Stripe API for a Harry Potter themed Rails online store demo app. I followed the Stripe boilerplate code, so I currently have the amount set at a hardcoded value of $1.00. In my shopping cart, there is a method that displays the total cost of all items in the cart. That works fine, but I can't figure out how to pass that value to the Charges controller so that it sets that as the amount of the payment.
I'm fairly new to Rails, so any helpful explanations would be greatly appreciated.
Here is my charges/new.html.erb file:
<%= form_tag charges_path do %>
<article>
<% if flash[:error].present? %>
<div id="error_explanation">
<p><%= flash[:error] %></p>
</div>
<% end %>
<label class="amount">
<span>Amount: $1.00</span>
</label>
</article>
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
data-description="A month's subscription"
data-amount="100"
data-locale="auto"></script>
<% end %>
Here is my Charges controller:
class ChargesController < ApplicationController
include CurrentCart
before_action :set_cart, only: [:new, :create]
def new
end
def create #METHOD IS CALLED AFTER PAYMENT IS MADE
# Amount in cents
#amount = 100
customer = Stripe::Customer.create(
:email => params[:stripeEmail],
:source => params[:stripeToken]
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => #amount,
:description => 'Witch or Wizard',
:currency => 'usd'
)
Cart.destroy(session[:cart_id])
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to new_charge_path
end
end
Here is my carts/show.html.erb file:
<p id="notice"><%= notice %></p>
<h2>My Cart</h2>
<table class="table table-responsive table-striped">
<thead>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Total Price in Galleons</th>
<th>Total Price in Muggle Currency</th>
</tr>
<tbody>
<%= render(#cart.line_items) %>
<tr>
<td>Total</td>
<td><%= number_to_currency(#cart.total_price * 7.35) %></td>
<td></td>
<td></td>
</tr>
</tbody>
</thead>
</table>
<br>
<div class="row">
<div class="col-md-3">
<div class="row">
<div class="col-md-4">
<%= link_to 'Back', products_path, :class => 'btn btn-primary whiteText' %>
</div>
<div class="col-md-4">
<%= link_to "Checkout", new_charge_path, :class => 'btn btn-success whiteText' %>
</div>
<div class="col-md-4">
<%= link_to 'Empty Cart', #cart, method: :delete, data: {confirm: 'Are you sure you want to empty your cart?'}, :class => 'btn btn-danger whiteText' %>
</div>
</div>
</div>
<div class="col-md-9"></div>
</div>
Here is my Carts controller:
class CartsController < ApplicationController
before_action :set_cart, only: [:show, :edit, :update, :destroy]
rescue_from ActiveRecord::RecordNotFound, with: :invalid_cart
# GET /carts
# GET /carts.json
def index
#carts = Cart.all
end
# GET /carts/1
# GET /carts/1.json
def show
end
# GET /carts/new
def new
#cart = Cart.new
end
# GET /carts/1/edit
def edit
end
# POST /carts
# POST /carts.json
def create
#cart = Cart.new(cart_params)
respond_to do |format|
if #cart.save
format.html { redirect_to #cart, notice: 'Cart was successfully created.' }
format.json { render :show, status: :created, location: #cart }
else
format.html { render :new }
format.json { render json: #cart.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /carts/1
# PATCH/PUT /carts/1.json
def update
respond_to do |format|
if #cart.update(cart_params)
format.html { redirect_to #cart, notice: 'Cart was successfully updated.' }
format.json { render :show, status: :ok, location: #cart }
else
format.html { render :edit }
format.json { render json: #cart.errors, status: :unprocessable_entity }
end
end
end
# DELETE /carts/1
# DELETE /carts/1.json
def destroy
#cart.destroy if #cart.id == session[:cart_id]
session[:cart_id] = nil
respond_to do |format|
format.html { redirect_to root_path, notice: 'Cart was emptied.' }
format.json { head :no_content }
end
end
def update_quantity
#line_item.update_attribute(:quantity)
end
private
# Use callbacks to share common setup or constraints between actions.
def set_cart
#cart = Cart.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def cart_params
params.fetch(:cart, {})
end
def invalid_cart
logger.error "Attempt to access invalid cart #{params[:id]}"
redirect_to root_path, notice: 'Invalid cart'
end
end
Here is my Cart model:
class Cart < ApplicationRecord
has_many :line_items, dependent: :destroy
def add_product(product)
current_item = line_items.find_by(product_id: product.id)
if current_item
current_item.quantity += 1
else
current_item = line_items.build(product_id: product.id)
end
current_item
end
def total_price
line_items.to_a.sum {|item| item.total_price}
end
def convert_to_muggle(galleons)
line_items.to_a.sum {|item| item.convert_to_muggle}
end
end
And here is my routes file:
Rails.application.routes.draw do
resources :charges
resources :orders
resources :line_items
resources :carts
devise_for :users
match 'users/:id' => 'users#destroy', :via => :delete, :as => :admin_destroy_user
resources :users, only: [:index, :show, :edit, :update]
root 'products#index'
resources :products
controller :products do
post '/products/destroy' => 'products#destroy', as: :destroy
get '/products/add_to_cart' => 'products#add_to_cart', as: :add_to_cart
get '/products/remove_from_cart' => 'products#remove_from_cart', as: :remove_from_cart
end
controller :line_items do
post '/line_items/increase_quantity' => 'line_items#increase_quantity', as: :increase_quantity
end
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
In your charges_controller, change the amount:
#amount = #cart.total_price * 735
And your charges/new.html.erb:
<span>Amount: <%= number_to_currency(#cart.total_price * 7.35) %></span>
and
data-amount="<%= #cart.total_price * 735 %>"
Let me know if that helps.

Rails, edit link will redirect but update button won't work

In my rails app I have this edit form that does not seem to work properly. If I enter the edit-site through any link, everything will look fine but the form submit button will not work. If I refresh the window it works fine.
Edit.html.erb
<div class="alien-choice">
<h2 class="player_name"><%= current_user.username %></h2>
<p> Choose <span>0</span>/2 Power</p>
<%= form_for [#gameround, #currentplayer] do |f| %>
<% alleflares = #currentplayer.flares %>
<% alleflares.each { |val|
printAlien = Alien.find_by_title(val)
%>
<div class="alien_wrap">
<h3><%= printAlien.title %> <span>[<%= printAlien.expansion.abbr %>]</span></h3>
<label for="<%= printAlien.title %>">
<div class="alien" style="background-image: url(<%= printAlien.avatar.url %>)">
</label>
<%= f.check_box(:aliens, { :multiple => true, :id => printAlien.title, :class => 'choosealiens'}, printAlien.title, nil) %>
</div>
</div>
<% } %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<%= link_to 'Back', gameround_currentplayers_path %>
The controller
class CurrentplayersController < ApplicationController
before_action :set_currentplayer, only: [:show, :edit, :update]
# GET /currentplayers
# GET /currentplayers.json
def index
#currentplayers = Currentplayer.all
end
# GET /currentplayers/1
# GET /currentplayers/1.json
def show
#gameround = Gameround.find(params[:gameround_id])
#currentplayer = #gameround.currentplayers.find(params[:id])
current_user
end
# GET /currentplayers/new
def new
#gameround = Gameround.find(params[:gameround_id])
#currentplayer = Currentplayer.new
end
# GET /currentplayers/1/edit
def edit
#gameround = Gameround.find(params[:gameround_id])
#currentplayer = #gameround.currentplayers.find(params[:id])
end
# POST /currentplayers
# POST /currentplayers.json
def create
#gameround = Gameround.find(params[:gameround_id])
#currentplayer = #gameround.currentplayers.create(currentplayer_params);
respond_to do |format|
if #currentplayer.save
format.html { redirect_to #gameround, notice: 'Currentplayer was successfully created.' }
format.json { render :show, status: :created, location: #currentplayer }
else
format.html { render :new }
format.json { render json: #currentplayer.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /currentplayers/1
# PATCH/PUT /currentplayers/1.json
def update
#gameround = Gameround.find(params[:gameround_id])
#currentplayer = #gameround.currentplayers.find(params[:id])
if #currentplayer.update(currentplayer_params)
redirect_to gameround_currentplayer_path
else
render 'edit'
end
end
# DELETE /currentplayers/1
# DELETE /currentplayers/1.json
def destroy
#gameround = Gameround.find(params[:gameround_id])
#currentplayer = #gameround.currentplayers.find(params[:id])
#currentplayer.destroy
respond_to do |format|
format.html { redirect_to '/play', notice: 'Currentplayer was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_currentplayer
#currentplayer = Currentplayer.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def currentplayer_params
params.require(:currentplayer).permit(:log_id, :flares, :winner, :bases, :gameround_id, aliens:[])
end
end
config.routes
Rails.application.routes.draw do
resources :gamerounds do
resources :currentplayers
end
I figured it out. It was just because the submit button was outside of the main div. Sorry for the trouble!
You want to create your routes into config/routes.rb as follows:
resources :current_players

Acts_as_taggable gem. Cloud

I have a list of categories. When you click on a category lets say Computers it should only show a tag cloud of the items in that category in this case Computers. Tags from the Mobile Phone category should not be showing.
Currently my tag cloud shows all tags across all categories.
Im using the Acts_as_tagable_gem https://github.com/mbleigh/acts-as-taggable-on
How would someone go about showing only the tags inside that category?
Here is my view. Please refer to tag_cloud
<p id="notice"><%= notice %></p>
<div class = "col-md-3">
<h1>
<strong><%= #category.name %></strong>
</h1>
</div>
<div class = "col-md-9">
<div id="tag_cloud">
<% tag_cloud Item.tag_counts, %w[s m l] do |tag, css_class| %>
<%= link_to tag.name, tag_path(tag.name, id: #category.id), class: css_class %>
<% end %>
</div>
</div>
<div class = "col-md-12">
<div class="line-separator"></div>
</div>
<div class = "col-md-12">
<div id="items" class="transitions-enabled">
<% #items.each do |item| %>
<div class="box panel panel-default">
<div class="itemlisttitle"><%= item.title %></div>
<%= link_to image_tag(item.image.url (:medium)), item %>
<div class ="panel-body">
<div class = "itemlistprice">$<%= item.price %></div>
<div class = "itemlistretailer"><%= image_tag item.user.avatar(:thumb) %> Retailer: <%= link_to item.user.username, item.user %></div>
</div>
</div>
<% end %>
</div>
</div>
Routes Please refer to the last line
Rails.application.routes.draw do
resources :categories
get 'password_resets/new'
get 'password_resets/edit'
get 'sessions/new'
resources :users
get 'user_items' => 'users#show_user_items'
root 'items#home'
get 'signup' => 'users#new'
get 'show' => 'users#show'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :items
get 'items_new' => 'items#new'
get 'tags/:tag', to: 'categories#show', as: :tag
Category Controller Please refer to show action
class CategoriesController < ApplicationController
before_action :set_category, only: [:show]
before_action :admin_user, only: [:destroy, :index, :edit]
def index
#categories = Category.all
end
def show
if params[:tag]
#items = Item.tagged_with(params[:tag])
else
#items = Item.where(category_id: #category.id).order("created_at DESC")
end
end
def new
#category = Category.new
end
def edit
end
def create
#category = Category.new(category_params)
respond_to do |format|
if #category.save
format.html { redirect_to #category, notice: 'Category was successfully created.' }
format.json { render :show, status: :created, location: #category }
else
format.html { render :new }
format.json { render json: #category.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #category.update(category_params)
format.html { redirect_to #category, notice: 'Category was successfully updated.' }
format.json { render :show, status: :ok, location: #category }
else
format.html { render :edit }
format.json { render json: #category.errors, status: :unprocessable_entity }
end
end
end
def destroy
#category.destroy
respond_to do |format|
format.html { redirect_to categories_url, notice: 'Category was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_category
#category = Category.find(params[:id])
end
def category_params
params.require(:category).permit(:name, :parent_id)
end
# Confirms an admin user.
def admin_user
redirect_to(root_url) unless current_user.try(:admin?)
end
end

Acts As Votable Get Upvotes Error

Working with the Acts as Votable gem on my rails 4 app.
So far I have gotten everything working, except when I call get_upvotes and get_downvotes to display how many votes a post has, I get this error:
undefined method `get_upvotes' for #<Post:0x000001078b5f58>
Here is my Post view (_post.html.erb):
<%= post.name %>
<%= post.title %>
<%= post.content %><br>
<%= link_to 'Show', post %>
<% if can? :update, #post %>
<%= link_to 'Edit', edit_post_path(post) %>
<% end %>
<% if can? :destroy, #post %>
<%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %>
<% end %>
<%= link_to like_post_path(post), class: "like", method: :put do %>
<button type="button" class="btn btn-info" aria-label="Left Align">
<span class="glyphicon glyphicon-thumbs-up glyphicon-align-center" aria-hidden="true"></span>
<span class="badge"><%= post.get_upvotes.size %></span>
</button>
<% end %>
<%= link_to dislike_post_path(post), class: "like", method: :put do %>
<button type="button" class="btn btn-info" aria-label="Left Align">
<span class="glyphicon glyphicon-thumbs-down glyphicon-align-center" aria-hidden="true"></span>
<span class="badge"><%= post.get_downvotes.size %></span>
</button>
<% end %>
Here is my controller (posts_controller.rb):
class PostsController < ApplicationController
load_and_authorize_resource
before_action :set_post, only: [:show, :edit, :update, :destroy, :upvote, :downvote]
def index
end
def show
end
def new
end
def edit
end
def create
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
def upvote
#post = Post.find(params[:id])
#post.upvote_from current_user
redirect_to :back
end
def downvote
#post = Post.find(params[:id])
#post.downvote_from current_user
redirect_to :back
end
private
def set_post
#post = Post.find(params[:id])
end
def post_params
params.require(:post).permit(:name, :title, :content, :image, :image2, :video1, :video2)
end
end
and my model (post.rb):
class Post < ActiveRecord::Base
acts_as_voter
belongs_to :user
end
user model (user.rb):
class User < ActiveRecord::Base
acts_as_votable
has_many :posts
end
and lastly my routes (routes.rb):
resources :posts do
member do
put "like" => "posts#upvote"
put "dislike" => "posts#downvote"
end
end
Does anyone know why get_upvotes isn't working?
Reading the docs, it looks like get_upvotes is a method on the acts_as_votable, not the acts_as_voter.
I don't know much about the context of your code, but shouldn't the User be voting on the Post, like so:
class Post < ActiveRecord::Base
acts_as_votable
belongs_to :user
end
User model:
class User < ActiveRecord::Base
acts_as_voter
has_many :posts
end
See: https://github.com/ryanto/acts_as_votable#votable-models

Rails : error param is missing or the value is empty : annonce

I want to creat a classified ads website for a project in school and I try to create a form to send a message by email at a member of the website. The email adress is contained in a model which is name "Membre" and this model is link at a model who is name "Annonce" which contained the ad.
But when I try to create that, I have this error :
param is missing or the value is empty: annonce
app/controllers/annonces_controller.rb:104:in `annonce_params'
app/controllers/annonces_controller.rb:29:in `create'
Here the Ad controller :
class AnnoncesController < ApplicationController
before_action :set_annonce, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!, :except => [:index]
# GET /annonces
# GET /annonces.json
def index
#annonces = Annonce.all
end
# GET /annonces/1
# GET /annonces/1.json
def show
end
# GET /annonces/new
def new
#annonce = Annonce.new
end
# GET /annonces/1/edit
def edit
end
# POST /annonces
# POST /annonces.json
def create
#annonce = Annonce.new(annonce_params)
#annonce.membre_id = current_membre.id
respond_to do |format|
if #annonce.save
format.html { redirect_to #annonce, notice: t('annonce_cree_succes') }
format.json { render :show, status: :created, location: #annonce }
else
format.html { render :new }
format.json { render json: #annonce.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /annonces/1
# PATCH/PUT /annonces/1.json
def update
respond_to do |format|
if #annonce.update(annonce_params)
format.html { redirect_to #annonce, notice: t('annonce_cree_succes') }
format.json { render :show, status: :ok, location: #annonce }
else
format.html { render :edit }
format.json { render json: #annonce.errors, status: :unprocessable_entity }
end
end
end
# DELETE /annonces/1
# DELETE /annonces/1.json
def destroy
#annonce.destroy
respond_to do |format|
format.html { redirect_to annonces_url, notice: t('annonce_destroy_succes') }
format.json { head :no_content }
end
end
# GET /annonces/contact/1
def contact
#form_contact = FormContact.new
if #form_contact.valid?
#MembreMailer.email_contact(Membre.where(:id => #annonce.membre_id ),current_membre,#annonce,#message)
#annonce = Annonce.find(params[:id])
#recepteur = Membre.where(:id => #annonce.membre_id )
#membre = current_membre
mail(:to => "#{recepteur.pseudo} <#{recepteur.email}>", subject: 'Reponse à l\'une de vos annnonces')
redirect_to root
end
end
# GET /annonces/report/1
def report
#annonce = Annonce.find(params[:id])
end
private
def authenticate_user!
if membre_signed_in?
#super
else
redirect_to login_path, :notice => 'Merci de vous connecter pour effecter cette action'
## if you want render 404 page
## render :file => File.join(Rails.root, 'public/404'), :formats => [:html], :status => 404, :layout => false
end
end
# Use callbacks to share common setup or constraints between actions.
def set_annonce
#annonce = Annonce.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def annonce_params
params.require(:annonce).permit(:id, :titre, :corps, :prix, :membre_id, :categorie, :created_at, :image)
end
Here the view contact :
<div class="col-md-offset-2 col-md-8 well panel panel-default">
<h2 class='panel-heading text-center'><%= t('contacter') %></h2>
<div class="panel-body text-center">
<%= form_for(:form_contact, :url => {:action => :create}) do |f| %>
<div class="field block-center">
<%= f.label "message" %></br>
<%= f.text_area(:message, size: "50x15")%>
</div></br>
<div class="actions form-group col-md-offset-3 col-md-6">
<%= submit_tag t('envoyer'), :class => "btn btn-large btn-block btn-primary" %>
</div>
<% end %>
</div>
</div>
<p class='row'> </p>
And here the FormContact class:
class FormContact < ActiveForm::Base
attr_accessor :message
validates_presence_of :message
def new
#form_contact = FormContact.new(login_form)
end
def index
#form_contact = FormContact.new
end
private
def login_form
params.require(:form_contact).permit(:message)
end
end
How can I fix that ?
Thanks in advance
This is routing error, you should call the create method of FormContactsController, not AnnoncesController create method.
<%= form_for(:form_contact, :url => {:controller => "FormContactsController", :action => :create}) do |f| %>

Resources