Populating foreign key on create action - ruby-on-rails

I have a Evaluation similar to this:
Evaluation.rb
has_one :cardio
has_one :neuro
Cardio.rb
belongs_to :evaluation
Neuro.rb
belongs_to :evaluation
My evaluation controller is similar to this:
def create
#patient = Patient.find(params[:id])
#evaluator = Evaluator.find(session[:evaluator_id]) if session[:evaluator_id]
#evaluation = Evaliation.new(:patient_id => #patient.id, :evaluator_id => #evaluator.id)
#neuro = Neuro.new(:evaluation_id => #evaluation.id)
#cardio = Cardio.new(:evaluation_id => #evaluation.id)
if (#evaluation.save! && #neuro.save! && #cardio.save!)
redirect_to evaluation_path(#evaluation.id), :notice => "Evaluation created"
else
render ("new")
end
end
When the evaluation is created the cardio and neuro are created too, but with null evaluation_id.
I tried to move the #cardio = Cardio.new(:evaluation_id => #evaluation.id) inside the if but it didnt worked too.

#evaluation won't have an id set until you save it, so #evaluation.id will be nil when you are creating #neuro and #cardio. In other words:
#evaluation = ...
if (#evaluation.save!)
#neuro = Neuro.new(:evaluation_id => #evaluation.id)
#cardio = Cardio.new(:evaluation_id => #evaluation.id)
if (#neuro.save! && #cardio.save!)
redirect_to evaluation_path(#evaluation.id), :notice => "Evaluation created"
else
render ("new")
end
else
render ("new")
end

Related

How to test destroy failure in ruby-on-rails

everyone.
I'm gonna test an active record object destroy failure but I've problems creating a failure situation.
I have a before_filter method called 'require_user_payment_info' which validates the #payment_info object before the delete method is called, so I can't create a 'bad' #payment_info object before the delete method is called.
Here's the require_user_payment_info method:
def require_user_payment_info
#payment_info = credit_card_model.slave.find_by_user_guid(user_guid)
if !#payment_info || #payment_info.user_guid != user_guid
redirect_to(:controller => 'store', :action => 'index') and return false
else
if((#payment_info.card_expires_year.to_i < Date.today.year) ||
((#payment_info.card_expires_month.to_i < Date.today.month) && (#payment_info.card_expires_year.to_i == Date.today.year)))
#payment_info.card_account_public = "" #clear this out so the user is forced to re-enter the credit card number
#payment_info.valid?
flash.now[:error] = t('ui_flash_errors.card_expired_error')
end
end
end
And the actual delete method:
def delete
# required to be called via a delete request
redirect_to :action => 'edit' and return if !request.delete?
if #payment_info.destroy
flash[:notice] = "Delete SUCCESSFUL"
redirect_to :action => 'new'
else
flash[:error] = "Delete failed"
redirect_to :action => 'edit'
end
Any ideas?
This is my solution:
def test_delete
payment_info = Factory.create(:payment_info, :user_guid=>#user.guid, :card_expires_month=>'04',
:card_expires_year=>(Date.today.year+2).to_s, :cardholder_city=>"test city",
:cardholder_state=>'NC', :cardholder_country=>'US', :cardholder_zip=>'27612')
PaymentInfo.any_instance.stubs(:destroy).returns(false)
delete(:delete, {}, #session)
assert_response(:redirect)
assert_equal false, assigns(:payment_info).blank?
assert_redirected_to({:controller=>'account', :action=>'edit'})
assert_equal flash[:error], "There was an error deleting your credit card information. Please try again."
end

RAILS: db count is always 0 in spec

Here is a simple case of spec in Rails 4.2:
it "returns redirect to Save & Copy" do
user_access = FactoryGirl.create(:user_access, :action => 'create', :resource =>'simple_orderx_orders', :role_definition_id => #role.id, :rank => 1,
:sql_code => "")
session[:user_id] = #u.id
q1 = FactoryGirl.create(:simple_orderx_order)
q = FactoryGirl.attributes_for(:simple_orderx_order)
FactoryGirl.create(:project_misc_definitionx_misc_definition, :resource_id => q1.id, :resource_string => 'simple_orderx_orders', definition_category: 'production_step')
expect {
get 'create', {:order => q, commit: I18n.t('Save & Copy')}
expect(response).to redirect_to URI.escape(SUBURI + "/view_handler?index=0&msg=Successfully Saved!")
}.to change(ProjectMiscDefinitionx::MiscDefinition.all.reload, :count).by(1)
end
end
In debugger, there is a new record being added to table MiscDefinition and MiscDefinition.all.count is 2, but in spec the ProjectMiscDefinitinox::MiscDefinition.all.count is always 0 and the spec case fails. What could cause the counting error in spec?
Here is the create in controller:
def create
#order = SimpleOrderx::Order.new(new_params)
#order.last_updated_by_id = session[:user_id]
#order.entered_by_id = session[:user_id]
#order.fort_token = session[:fort_token]
copy_steps(#order) if params[:commit] == I18n.t('Save & Copy') #copy mfg steps from previous order
if #order.save
copy_steps(#order.reload) if params[:commit] == I18n.t('Save & Copy') #copy mfg steps from previous order
redirect_to URI.escape(SUBURI + "/view_handler?index=0&msg=Successfully Saved!")
else
#erb_code = find_config_const('order_new_view', session[:fort_token], 'simple_orderx')
flash[:notice] = t('Data Error. Not Saved!')
render 'new'
end
end
def copy_steps(order)
obj = Order.where('drawing_num = ? AND id != ?', order.drawing_num, order.id).order('created_at DESC') if order.drawing_num.present? #find the previous order of the same drawing#
obj = Order.where('part_num = ? AND id != ?', order.part_num, order.id).order('created_at DESC') if obj.blank? && order.part_num.present?
obj = Order.where('part_name Like ? AND id != ?', "%#{order.part_name}%", order.id).order('created_at DESC') if obj.blank? && order.part_name.present?
copied = false
obj.limit(4).each do |o|
SimpleOrderx.production_step_class.where('resource_id = ? AND resource_string = ? AND definition_category = ?', o.id, params[:controller].sub('/', '_'), 'production_step').each do |r|
new_step = SimpleOrderx.production_step_class.new()
new_step = r.dup
new_step.resource_id = order.id
begin
new_step.save
copied = true
rescue => e
flash[:notice] = 'Error in copying production steps: ' + e.message
end
end
return if copied
end if obj.present?
end

Rails after create not functioning as expected

In my Case model (case.rb) I have a few after_create callbacks. One of which is not functioning as expected.
By that I mean when I run it in the console, it works, but when creating it in the controller via an HTTP request, it does not.
Model code (the problem is with :create_case_users not working):
after_create -> { redis_check(true) },
:create_case_users,
:create_manager,
:pusher_trigger
And the create_case_users method:
def create_case_users
cus = CaseUser.where(:case_id => self.id, :is_age => 1)
cus.each do |cu|
connections = Connection.where({ :cases => 1, :con_id => cu.user_id })
connections.each do |connection|
if connection.user_id && connection.connection_id
case_user = CaseUser.new
case_user.case_id = self.id
case_user.user_id = connection.user_id
case_user.email = connection.cases_emails
case_user.is_age = 0
case_user.cm = 0
case_user.save!
end
end
end
end
When running the above snippet in the console of my app, specifying the Case to run it for, it works & creates the records I expect.
When I POST to /api/v1/cases, it hits this controller action:
#case = Case.new(case_params)
#case.current_user(#current_user)
if #case.save
render :json => #case,
:root => "case",
:status => :created,
:location => #case,
:serializer => CaseShowSerializer,
:current => #current_user
else
render :json => #case.errors,
:status => :unprocessable_entity
end
What could be the problem? The after create callback after create_case_users runs and functions as expected, meaning create_case_users isn't returning false.
Edit:
When running Case.find(500).create_case_users in the console it works.

how do I check student_id before input student class record?

My thought of this programming content as below: 'adult' symbolize the student data table and 'adultclasses' symbolize course selection data table.
When the data keyin person input the student data,they have to avoid input the student_id which not existing in adult content. However, I’ve try several times still fail.
def create
#adult_class = AdultClasse.new(params[:adult_classe])
#adults_session_descriptions = AdultsSessionDescription.all
if
#adult_class = #adult_class.find(:student_id) == Adult.find_by_student_id(:student_id)
flash[:notice] = "no this student id record!"
redirect_to:action => :index
else
respond_to do |format|
if #adult_class.save
format.html { redirect_to(#adult_class, :notice => 'adult classe was successfully created.') }
format.xml { render :xml => #adult_class, :status => :created, :location => #adult_class }
else
format.html { render :action => "new" }
format.xml { render :xml => #adult_class.errors, :status => :unprocessable_entity }
end
end
end
Because I was mistaken use plural names to build the program, I’ve made up in adultclasse.rb as below:
# encoding: utf-8
class AdultClasse < ActiveRecord::Base
set_table_name "adult_classes"
belongs_to :adult
#has_many :adults_classe_ship
#has_many :adult, :through => :adults_classe_ship
validates :student_id, :presence => {:message => "please input student id"},
:length => {:message => "too short or too long", :minimum => 4, :maximum => 12}
end
this is model Adult.rb
# encoding: utf-8
class Aadult < ActiveRecord::Base
before_save :fix_cname
def age
now = Time.now.utc.to_date
dob = self.birthday
now.year - dob.year - ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? 0 : 1)
end
private
def fix_cname
self.cname = self.cname.gsub(/[\w\s\b\$[:punct:]]/ , '')
end
#has_many :adults_classe_ship, :dependent => :destroy
#has_many :adult_classe, :through => :adults_classe_ship

Single model different view and CRUD functionality in RubyOnRails3

As a new to Ruby on rails, I stumble on a part of my app. I read the basics of RoR framework and know the 'convention over configuration' feature of rails MVC. I have two tables, one is apps_events and another is apps_events_attributes. The id of the first one is the foreign key of the second and in has many relationship. The app_events table has a field of foreign key attribute 'app_id', so selecting on a particular app I will be redirected to its events and attributes. There is also a field called 'is_standard' which actually distinguish the event type whether it's a Standard or Custom event.
Now I have to render those events and its attributes of a particular app in two different tab on the view layer with it's attributes using nested_form_for feature. User can toggle to Standard and Custom event through this tab click. Can anyone suggest me how will I achieve the same and can show me the ideal flow of this scenario (model name and checking part of 'is_standard', propagate the same in controller and render to the view)?
By the way, can I use different controller over the same model and if I do the same then is it capable of doing the same CRUD functionality for different Event and its attributes?
I have all it done alone and it is not very hard what I think at first, all trick is done by JQuery... and share the concept if somebody got same problem as me
My Models are
class AppsEvent < ActiveRecord::Base
belongs_to :app
has_many :apps_events_attributes, :foreign_key => 'apps_event_id',
:class_name => 'AppsEventsAttribute',
:dependent => :destroy
accepts_nested_attributes_for :apps_events_attributes,
:reject_if => lambda { |a| (a[:name].blank? && a[:description].blank?) },
:allow_destroy => true
validates_presence_of :description
validates_presence_of :name
validates_presence_of :code
validates_presence_of :apps_events_attributes, :message => "can't be empty"
end
and
class AppsEventsAttribute < ActiveRecord::Base
set_table_name :apps_events_attributes
belongs_to :apps_event, :foreign_key => 'apps_event_id'
attr_accessible :id, :apps_event_id, :name, :description, :attribute_type, :is_std, :created_at, :updated_at
def type
self.attribute_type
end
end
and My Controller is...
class AppsEventsController < ApplicationController
layout :layout_by_resource
before_filter :initialize_default_app
before_filter :check_permission
before_filter :load
def load
#app = current_user.find_app(params[:app_id])
#apps_events = AppsEvent.where(:app_id => #app.id)
#apps_event = AppsEvent.new
end
def index
#app = current_user.find_app(params[:app_id])
#default_app = App.default(current_user)
#apps_events = AppsEvent.where(:app_id => #app.id)
#apps_event_jsons = Hash.new
#apps_events.each do |app_event|
json = Hash.new
json['User_ID'] = 548741213
json['Session_ID'] = 2568639390
json['Action_Type'] = app_event.code
json['eventsData'] = {}
app_event.apps_events_attributes.each do |apps_event_attributes|
if (apps_event_attributes.attribute_type == 'Integer')
json['eventsData'][apps_event_attributes.name] = 1234
elsif (apps_event_attributes.attribute_type == 'Float')
json['eventsData'][apps_event_attributes.name] = 1234.23
else
json['eventsData'][apps_event_attributes.name] = 'abcd'
end
end
#apps_event_jsons[app_event.id] = json
end
end
def new
#apps_event = AppsEvent.new
#app = current_user.find_app(params[:app_id])
#apps_event.app_id = #app.id
#apps_event.apps_events_attributes.build
#action = 'create'
render 'edit'
end
def edit
#app = current_user.find_app(params[:app_id])
#apps_event = AppsEvent.find(params[:id])
#action = 'update'
end
def create
#apps_event = AppsEvent.new(params[:apps_event])
#show_custom_event = 'true'
#apps_event.name = #apps_event.name.strip
respond_to do |format|
if #apps_event.save
format.html {
redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
:notice => "Successfully created #{#apps_event.name} custom definition.")
}
format.js {
flash[:notice] = 'Successfully created event.'
#apps_events = AppsEvent.where(:app_id => #app.id)
}
else
#app = current_user.find_app(params[:app_id])
if (#apps_event.apps_events_attributes == nil || #apps_event.apps_events_attributes.size <= 0)
#apps_event.apps_events_attributes.build
end
#apps_event.populate_code
#action = 'create'
format.html {
redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
:alert => "Error in creating #{#apps_event.name} custom definition.")
}
format.js
end
end
end
def update
#apps_event = AppsEvent.find(params[:apps_event][:id])
params[:apps_event][:name] = params[:apps_event][:name].strip
respond_to do |format|
if #apps_event.update_attributes(params[:apps_event])
format.html {
if(#apps_event.is_std == 'y')
redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
:notice => "Successfully updated #{#apps_event.name} standard definition.")
else
redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
:notice => "Successfully updated #{#apps_event.name} custom definition.")
end
}
format.js {
flash[:notice] = 'Successfully updated event.'
#apps_events = AppsEvent.where(:app_id => #app.id)
render :nothing => true
}
else
#app = current_user.find_app(params[:app_id])
if (#apps_event.apps_events_attributes == nil || #apps_event.apps_events_attributes.size <= 0)
#apps_event.apps_events_attributes.build
end
#apps_event.populate_code
#action = "update"
format.html {
if(#apps_event.is_std == 'y')
redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
:alert => "Error in updating #{#apps_event.name} standard definition.")
else
redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
:alert => "Error in updating #{#apps_event.name} custom definition.")
end
}
format.js
end
end
end
def delete
if AppsEvent.delete(params[:id])
redirect_to "/app/#{params[:app_id]}/apps_events", :notice => "Successfully deleted #{#apps_event.name} custom definition."
else
redirect_to "/app/#{params[:app_id]}/apps_events",
:alert => "Error in deleting #{#apps_event.name} custom definition."
end
end
end
and I have 5 view files which are index.html.erb, edit.js.erb, _form_custom.html.erb, _form_standard.html.erb and _events.html.erb beside that have also a helper file for update, create and delete using ajax call by setting remote => true. In index file I am doing partial rendering all events(_events.html.erb) and here I done the trick :P
My _events.html.erb
<% for apps_event in #apps_events %>
<% if (apps_event.is_std == 'y') %>
<div class="standardEvent showStandard">
<ul>
<li class="column_1"><span style="font-weight: bold;"><%= apps_event.name %></span></li>
<li class="column_2"><span><%= apps_event.code %></span></li>
<li class="column_3"><span><%= apps_event.description %></span></li>
<li class="column_4">
<%= link_to edit_apps_event(apps_event) %>
</li>
<li class="column_5">
</li>
</ul>
</div>
<% else %>
<div class="customEvent showCustom" style="display:none">
<ul>
<li class="column_1"><span style="font-weight: bold;"><%= apps_event.name %></span></li>
<li class="column_2"><span><%= apps_event.code %></span></li>
<li class="column_3"><span><%= apps_event.description %></span></li>
<li class="column_4">
<%= link_to edit_apps_event(apps_event) %>
</li>
<li class="column_5">
<%= remove_apps_event_prompt_link(apps_event) %>
</li>
</ul>
</div>
<% end %>
<div class="clrBoth"></div>
<% end %>
now you can figure out the left part mean -- JQuery part to hide or show a div.

Resources