Not getting any value back from function defined in controller - ruby-on-rails

This is my controller. def random_generate is not giving me any output, and when I create the object, length is there but random_primer_generated is empty. Can someone help me?
class GeneratorsController < ApplicationController
before_action :set_generator, only: [:show, :edit, :update, :destroy]
helper_method :random_generate
# GET /generators
# GET /generators.json
def index
#generators = Generator.all
end
# GET /generators/1
# GET /generators/1.json
def show
end
# GET /generators/new
def new
#generator = Generator.new
end
# GET /generators/1/edit
def edit
end
# POST /generators
# POST /generators.json
def create
#generator = Generator.new(generator_params)
respond_to do |format|
if #generator.save
format.html { redirect_to #generator, notice: 'Generator was successfully created.' }
format.json { render action: 'show', status: :created, location: #generator }
else
format.html { render action: 'new' }
format.json { render json: #generator.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /generators/1
# PATCH/PUT /generators/1.json
def update
respond_to do |format|
if #generator.update(generator_params)
format.html { redirect_to #generator, notice: 'Generator was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #generator.errors, status: :unprocessable_entity }
end
end
end
# DELETE /generators/1
# DELETE /generators/1.json
def destroy
#generator.destroy
respond_to do |format|
format.html { redirect_to generators_url }
format.json { head :no_content }
end
end
def random_generate
if #generator.choice == 'Randomly'
length = #generator.primer_length
chars = 'atgc'
seq = ''
#length = length.to_i
length.times { seq << chars[rand(chars.size)] }
#generator.random_primer_generated = seq
end
return #generator.random_primer_generated
end
private
# Use callbacks to share common setup or constraints between actions.
def set_generator
#generator = Generator.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def generator_params
params.require(:generator).permit(:primer_length, :choice_random_primer_generated)
end
end
This is my Form_VIEW (to get the user's data - length and choice):
<%= form_for (#generator ) do |f| %>
<% if #generator.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#generator.errors.count, "error") %> prohibited this generator from being saved:</h2>
<ul>
<% #generator.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<label>Primer Length</label><br>
<%= f.number_field :primer_length %>
</div>
<label>Selection :</label><br>
<label>Randomly</label>
<%= radio_button_tag(:choice_random_primer_generated, 'Randomly')%>
<%= button_to('Generate', random_generate_generator_path(#generator))%>
<% end %>

Note: the form may be a red herring here. If you only want the code to be randomly generated when the user explicitly clicks that button, and NOT after every create or save, then you don't want any callbacks. You're doing it the right way. The only thing you are missing is the save call at the end of your method, and you'll also want to redirect the user back to a page.
However, if you DO want generate to happen after EVERY create or update, then you should probably change that button_to call to f.submit, and move that random_generate code to your model. Then, you can use rails callback for after_save and call that method from there within your controller.
More info:
http://guides.rubyonrails.org/active_record_callbacks.html

You are not calling your helper_method anywhere. When you post the form and it reaches the server, the create method is called. The helper_method is not triggered, therefore you are not creating a random number.
I didn't understand it very well, but what are you trying to randomize? Why don't you simply use a rand(999) to randomize numbers for example?

It looks like you want to call random_generate after your new and create action, but you are not calling it. All you have to do is change helper_method :random_generate to after_action :random_generate, only: [:create, :new]
You also want to make sure to save your new record in random_generate. You don't need the return #genator.random_primer_generated. See below:
def random_generate
if #generator.choice == 'Randomly'
length = #generator.primer_length
chars = 'atgc'
seq = ''
#length = length.to_i
length.times { seq << chars[rand(chars.size)] }
#generator.random_primer_generated = seq
end
#generator.save!
end

Related

If user has at least one then show something else show other

I am writing a basic index page where I want to show a user a list of their credits cards if they have any, else I want to show them an add credit card button.
I know the statement is something like if current_user >1 credit_card
I have user model using devise and a credit_card model and basically I want to show the following.
<% if current_user has atleast 1(>1) credit_card>
show this
<% else %>
show that
<% end %>
Credit_Cards Controller
class CreditCardsController < ApplicationController
before_action :authenticate_user!
before_action :set_credit_card, only: [:show, :edit, :update, :destroy]
# GET /credit_cards
# GET /credit_cards.json
def index
#credit_cards = current_user.credit_cards
#credit_card_debt = current_user.credit_cards.sum(:card_balance)
#credit_limit = current_user.credit_cards.sum(:card_limit)
#available_credit = current_user.credit_cards.sum(:card_limit) - current_user.credit_cards.sum(:card_balance)
end
# GET /credit_cards/1
# GET /credit_cards/1.json
def show
end
# GET /credit_cards/new
def new
#credit_card = current_user.credit_cards.build
end
# GET /credit_cards/1/edit
def edit
end
# POST /credit_cards
# POST /credit_cards.json
def create
#credit_card = current_user.credit_cards.new(credit_card_params)
respond_to do |format|
if #credit_card.save
format.html { redirect_to #credit_card, notice: 'Credit card was successfully created.' }
format.json { render :show, status: :created, location: #credit_card }
else
format.html { render :new }
format.json { render json: #credit_card.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /credit_cards/1
# PATCH/PUT /credit_cards/1.json
def update
respond_to do |format|
if #credit_card.update(credit_card_params)
format.html { redirect_to #credit_card, notice: 'Credit card was successfully updated.' }
format.json { render :show, status: :ok, location: #credit_card }
else
format.html { render :edit }
format.json { render json: #credit_card.errors, status: :unprocessable_entity }
end
end
end
# DELETE /credit_cards/1
# DELETE /credit_cards/1.json
def destroy
#credit_card.destroy
respond_to do |format|
format.html { redirect_to credit_cards_url, notice: 'Credit card was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_credit_card
#credit_card = CreditCard.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def credit_card_params
params.require(:credit_card).permit(:card_name, :card_provider, :points_provider, :interest_rate, :card_balance, :card_limit, :user_id )
end
end
Credit Card Model
class CreditCard < ApplicationRecord
belongs_to :user
def credit_available
card_limit - card_balance
end
def annual_interest
card_balance * interest_rate
end
def minimum_payment
n = card_balance / 100
b = n * 1
i = card_balance * interest_rate
c = i / 12
c + b
end
def total_monthly_payment
total_monthly_payment = 0
#total_monthly_payment = total_monthly_payment + current_user.credit_cards.minimum_payment.sum
end
end
You have used this #credit_cards = current_user.credit_cards the line in the index action that's why you don't need to use current_user on the index.html.erb file because above line make sure you have credit card or no then your HTML file looks like
<% if #credit_cards.count >= 1 %>
show this
<% else %>
show that
<% end %>
Or you can use something like this
<% if #credit_cards.any? %>
show this
<% else %>
show that
<% end %>
Or you can use something like this
<% if current_user.credit_cards.count >= 1 %> #=> or current_user.credit_cards.any?
show this
<% else %>
show that
<% end %>
That's time you don't need this #credit_cards = current_user.credit_cards from index action
Here is you can see some if else basic explanation of Ruby The Bastards Book of Ruby

Rails model form f.select do not assign selected value to model key

sorry for this question but I'm struggling with this issue for hours now and can't find the answer anywhere.
Here is the thing, I have a rails app with "Reservation" and "Space" models with the following relations:
class Reservation < ActiveRecord::Base
belongs_to :space
belongs_to :user
end
class Space < ActiveRecord::Base
belongs_to :condo
has_many :reservations
end
When the user creates a new Reservation, in the form he gets to choose from a dropdown (f.select) the spaces available for him. The f.select in the form look like this:
<div class="field">
<%= #user_spaces = current_user.condo.spaces
f.select :space_id,
options_from_collection_for_select(#user_spaces, :id, :name), :prompt => "Select space"
%>
</div>
That select it supose to assign a value to the key "space_id" in the Reservation that is being created (column's table is created). But when I check the last reservation in Rails console, space_id value is "nil". What am I doing wrong?
Thank you very much for your help
Reservation controller file:
class ReservationsController < ApplicationController
before_action :set_reservation, only: [:show, :edit, :update, :destroy]
# GET /reservations
# GET /reservations.json
def index
#reservations = Reservation.all
end
# GET /reservations/1
# GET /reservations/1.json
def show
end
# GET /reservations/new
def new
#reservation = Reservation.new
end
# GET /reservations/1/edit
def edit
end
# POST /reservations
# POST /reservations.json
def create
#reservation = Reservation.new(reservation_params)
#user = current_user.id
#reservation.user_id = #user
respond_to do |format|
if #reservation.save
format.html { redirect_to #reservation, notice: 'Reservation was successfully created.' }
format.json { render :show, status: :created, location: #reservation }
else
format.html { render :new }
format.json { render json: #reservation.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /reservations/1
# PATCH/PUT /reservations/1.json
def update
respond_to do |format|
if #reservation.update(reservation_params)
format.html { redirect_to #reservation, notice: 'Reservation was successfully updated.' }
format.json { render :show, status: :ok, location: #reservation }
else
format.html { render :edit }
format.json { render json: #reservation.errors, status: :unprocessable_entity }
end
end
end
# DELETE /reservations/1
# DELETE /reservations/1.json
def destroy
#reservation.destroy
respond_to do |format|
format.html { redirect_to reservations_url, notice: 'Reservation was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_reservation
#reservation = Reservation.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def reservation_params
params.require(:reservation).permit(:eventdate)
end
end
Space controller file:
class SpacesController < ApplicationController
before_action :set_space, only: [:show, :edit, :update, :destroy]
# GET /spaces
# GET /spaces.json
def index
#spaces = Space.all
end
# GET /spaces/1
# GET /spaces/1.json
def show
end
# GET /spaces/new
def new
#space = Space.new
end
# GET /spaces/1/edit
def edit
end
# POST /spaces
# POST /spaces.json
def create
#space = Space.new(space_params)
respond_to do |format|
if #space.save
format.html { redirect_to #space, notice: 'Space was successfully created.' }
format.json { render :show, status: :created, location: #space }
else
format.html { render :new }
format.json { render json: #space.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /spaces/1
# PATCH/PUT /spaces/1.json
def update
respond_to do |format|
if #space.update(space_params)
format.html { redirect_to #space, notice: 'Space was successfully updated.' }
format.json { render :show, status: :ok, location: #space }
else
format.html { render :edit }
format.json { render json: #space.errors, status: :unprocessable_entity }
end
end
end
# DELETE /spaces/1
# DELETE /spaces/1.json
def destroy
#space.destroy
respond_to do |format|
format.html { redirect_to spaces_url, notice: 'Space was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_space
#space = Space.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def space_params
params.require(:space).permit(:name)
end
end
And full Reservation Form:
<%= form_for(#reservation) do |f| %>
<% if #reservation.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#reservation.errors.count, "error") %> prohibited this reservation from being saved:</h2>
<ul>
<% #reservation.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :eventdate %><br>
<%= f.date_select :eventdate %>
</div>
<div class="field">
<%= #user = current_user.condo.spaces
f.select :space_id,
options_from_collection_for_select(#user, :id, :name), :prompt => "Select space"
%>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
pretty sure you need to permit the space_id attribute in your strong params.
def reservation_params
params.require(:reservation).permit(:eventdate, :space_id)
end
whats happening is that when you go to create a reservation, youre passing in set of params, that is the output of reservation_params
#reservation = Reservation.new(reservation_params)
if space_id is not being permitted in your strong params, then it will be nil when created.
if this is not the issue, can you post what params are getting to the server, and what the output of reservation_params are.

Param is missing or the value is empty: ParameterMissing in ResultsController#update

I have a Result that belongs to a Website. After I create the website I also create the result and redirect to its edit page. Here I want to add some more values.
My problem is: When I try to update my Result, then I get:
param is missing or the value is empty: result
Request
Parameters:
{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"GRN/y/04Qbsm9DzlUAbUYF8ZSv2EMHnRZgBZY/6GMDlOBdq8V5Uncij9VRp51uydC6M/qc61jPWwpUehSuc5xA==", "data"=>["//html/body/div[position() = 3]/ul/li[position() = 16]/ul/li[position() = 2]/child::text()", "//html/body/div[position()
= 3]/ul/li[position() = 16]/ul/li[position() = 2]/p/a/child::text()", "//html/body/div[position() = 3]/ul/li[position() = 16]/ul/li[position() = 4]/child::text()", "//html/body/div[position()
= 3]/ul/li[position() = 16]/ul/li[position() = 5]/a/child::text()"], "commit"=>"Update Result", "id"=>"66"}
This is how my Result params looks like
def result_params
params.require(:result).permit(:data)
end
My model:
class Result < ActiveRecord::Base
belongs_to :website
attr_accessor :website_id
attr_accessor :data
serialize :data, Array
end
Here is my controller code:
class ResultsController < ApplicationController
before_action :set_result, only: [:show, :edit, :update, :destroy]
# GET /Results
# GET /Results.json
def index
#results = Result.all
end
# GET /Results/1
# GET /Results/1.json
def show
end
# GET /Results/new
def new
#result = Result.new
end
# GET /Results/1/edit
def edit
#result = Result.find(params[:id])
end
# POST /Results
# POST /Results.json
def create
#result = Result.new(result_params)
respond_to do |format|
if #result.save
format.html { redirect_to #result, notice: 'Result was successfully created.' }
format.json { render :show, status: :created, location: result }
else
format.html { render :new }
format.json { render json: #result.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /Results/1
# PATCH/PUT /Results/1.json
def update
respond_to do |format|
if #result.update(result_params )
format.html { redirect_to #result, notice: 'Result was successfully updated.' }
format.json { render :show, status: :ok, location: #result }
else
format.html { render :edit }
format.json { render json: #result.errors, status: :unprocessable_entity }
end
end
end
# DELETE /Results/1
# DELETE /Results/1.json
def destroy
#result.destroy
respond_to do |format|
format.html { redirect_to results_url, notice: 'Result was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_result
#result = Result.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def result_params
params.permit(:data => [])
end
end
My view:
<%= form_for(#result) do |f| %>
<% if #result.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#result.errors.count, "error") %> prohibited this result from being saved:</h2>
<ul>
<% #result.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<% if #result.website.url != nil %>
<%= atts = get_all_elements(#result.website.url)%>
<% atts.each do |p| %>
<div>
<%= check_box_tag "data[]", get_xpath_from_node(p)%>
<%= p.text %>
</div>
<%end%>
<% end%>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And this is the place where i call the edit result page:
def update
respond_to do |format|
if #website.update(website_params)
format.html { redirect_to #website, notice: 'Website was successfully updated.' }
format.json { render :show, status: :ok, location: #website }
else
format.html { render :edit }
format.json { render json: #website.errors, status: :unprocessable_entity }
end
end
end
Ive allready tryed every solution I could find, but none of them seemed to work for me.
The problem lies here:
params.require(:result).permit(:data)
From require documentation,
require ensures that a parameter is present. If it's present, returns
the parameter at the given key, otherwise raises an
ActionController::ParameterMissing error.
You are requiring result parameter but it's missing from the params. All your values are inside data param. Removing require should do the trick.
params.permit(:data)
If you want to keep require, wrap data inside result in forms.
I know, what you met. if you strong params is
def result_params
params.require(:result).permit(:data)
end
Your parameters should has the format like this
Parameters: {"result"=>{"data"=>"string"}}
and your parameters is just
Parameters: {"data"=>"string"}
so you should remove the "result"

Rails How to pass params in cross model system

I am unable to figure out the method to pass params to a link tag. What I want to do is When someone clicks on the Join Group link, the Membership model shall have a new row with group_id as the current group id and the user id as the current user id. The Membership model currently consists of two columns : user_id and group_id that maps users to groups. Can anyone help me with the mistake I am making.
Here is the code
Groups : show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Title:</strong>
<%= #group.title %>
</p>
<p>
<strong>Desc:</strong>
<%= #group.desc %>
</p>
<p>
<strong>Creator:</strong>
<%= #creator.first_name %>
</p>
<%= link_to 'Join Group', memberships_path(:group_id => #group.id, :user_id => current_user.id ), method: :post %>
<%= link_to 'Edit', edit_group_path(#group) %> |
<%= link_to 'Back', groups_path %>
and here is the Memberships controller
class MembershipsController < ApplicationController
before_action :set_membership, only: [:show, :edit, :update, :destroy]
# GET /memberships
# GET /memberships.json
def index
#memberships = Membership.all
end
# GET /memberships/1
# GET /memberships/1.json
def show
#membership = Membership.find(params[:id])
#user = User.find(#membership.user_id)
#group = Group.find(#membership.group_id)
end
# GET /memberships/new
def new
#membership = Membership.new
end
# GET /memberships/1/edit
def edit
end
# POST /memberships
# POST /memberships.json
def create
#membership = Membership.new(membership_params)
respond_to do |format|
if #membership.save
format.html { redirect_to #membership, notice: 'Membership was successfully created.' }
format.json { render :show, status: :created, location: #membership }
else
format.html { render :new }
format.json { render json: #membership.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /memberships/1
# PATCH/PUT /memberships/1.json
def update
respond_to do |format|
if #membership.update(membership_params)
format.html { redirect_to #membership, notice: 'Membership was successfully updated.' }
format.json { render :show, status: :ok, location: #membership }
else
format.html { render :edit }
format.json { render json: #membership.errors, status: :unprocessable_entity }
end
end
end
# DELETE /memberships/1
# DELETE /memberships/1.json
def destroy
#membership.destroy
respond_to do |format|
format.html { redirect_to memberships_url, notice: 'Membership was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_membership
#membership = Membership.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def membership_params
params.require(:membership).permit(:user_id, :group_id)
end
end
You should have a method in your controller that handles adding a user to a group, something like:
class MembershipsController < ApplicationController
...
def join_group
#user = User.find(params[:user]
#user.group_id = params[:group_id].to_i
end
...
end
Then routes.rb needs a path to that controller method:
get 'memberships/join_group' => 'memberships#join_group'
which will result in a path like memberships_join_group_path that you will use in your link_to:
<%= link_to 'Join Group', memberships_join_group_path(:group_id => #group.id, :user_id => current_user.id ) %>
The path you're currently using is sending params to your index method.
try
def create
#member = current_user.members.build(:group_id => params[:group_id])
if #member.save
flash[:notice] = "You have joined this group."
redirect_to members_path
else
flash[:error] = "Unable to join."
redirect_to members_path
end
end
and use memberships instead of members

Why does my code create an extra object?

I want to create an object with random sequence generated through the follow method. But after clicking the "Generate" button, it creates 2 objects (1 with all attributes null and the other 1 with the value I entered). Can someone tell me where's the problem?
CONTROLLER :
class GeneratorsController < ApplicationController
before_action :set_generator, only: [:show, :edit, :update, :destroy]
after_action :random_generate, only: [:create, :new, :edit]
# GET /generators
# GET /generators.json
def index
#generators = Generator.all
end
# GET /generators/1
# GET /generators/1.json
def show
end
# GET /generators/new
def new
#generator = Generator.new
end
# GET /generators/1/edit
def edit
end
# POST /generators
# POST /generators.json
def create
#generator = Generator.new(generator_params)
respond_to do |format|
if #generator.save
format.html { redirect_to #generator, notice: 'Generator was successfully created.' }
format.json { render action: 'show', status: :created, location: #generator }
else
format.html { render action: 'new' }
format.json { render json: #generator.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /generators/1
# PATCH/PUT /generators/1.json
def update
respond_to do |format|
if #generator.update(generator_params)
format.html { redirect_to #generator, notice: 'Generator was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #generator.errors, status: :unprocessable_entity }
end
end
end
# DELETE /generators/1
# DELETE /generators/1.json
def destroy
#generator.destroy
respond_to do |format|
format.html { redirect_to generators_url }
format.json { head :no_content }
end
end
def random_generate
if #generator.choice == 'Randomly'
length = #generator.primer_length
chars = 'ATGC'
seq = ''
length.times { seq << chars[rand(chars.size)] }
#generator.random_primer_generated = seq
end
#generator.save!
end
private
# Use callbacks to share common setup or constraints between actions.
def set_generator
#generator = Generator.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def generator_params
params.require(:generator).permit(:primer_length, :choice, :random_primer_generated)
end
end
VIEW :
<%= form_for (#generator ) do |f| %>
<% if #generator.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#generator.errors.count, "error") %> prohibited this generator from being saved:</h2>
<ul>
<% #generator.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<label>Primer Length</label><br>
<%= f.number_field :primer_length %>
</div>
<label>Selection :</label><br>
<label>Randomly</label>
<%= radio_button_tag(:choice, 'Randomly')%>
<%= button_to('Generate', random_generate_generator_path(#generator))%>
<% end %>
You have an after_action callback which triggers the random_generate action every time you display the new view. That's where your empty object comes from. You shouldn't need this after_action callback on new.

Resources