Attribute changes are not notified and table is not updated - ruby-on-rails

I want to update a table but the update SQL is not performed so the changes has no effect.
Details:
Originally issue.name us 'issue'. I want to change to 'qqqqqqqqqqqq'.
Controller:
def update
if params['cancel']
redirect_to(#issue)
return
end
#issue = Issue.find(params[:id])
logger.debug "original object"
logger.debug "#{#issue.to_yaml}"
logger.debug 'bulk attribute settings...'
#issue.attributes= params[:issue]
logger.debug "after bulk settings"
logger.debug "#{#issue.to_yaml}"
#issue.events.build(:note=>params[:issue][:description],:verb=>'Edited', :changes=>#issue.textalize_changes)
if #issue.save
logger.debug "after save"
logger.debug "#{#issue.to_yaml}"
redirect_to(#issue)
else
render :action => "edit"
end
end
One additional code fregment might be interesting is the textalize_changes:
def textalize_changes
r = ""
if changed?
changes.keys.each do |k|
r << "#{k.humanize} changed "
r << "from `#{translate(k,changes[k][0])}` "
r << "to `#{translate(k,changes[k][1])}`"
r << "<br/>"
end
end
r unless r.blank?
end
The result:
until the line #issue.save everything looks correct. I have checked that #issue contains all the changes i have made.
on the user interface no changes I have notified.
in the log no update SQL is visible. all relevant select and insert is presented but no update - so no change in table issues
even textalize_changes has not realize and changes in the object when checking for that (changed?)
If I manually change the attribute in at source code level by name=XXX it is working.
I don't know what to check or review at all. The code is so simple that i have no idea at all.
Here is the log of the operation:
original object
--- !ruby/object:Issue
attributes:
name: OTTO TEST 2
assigned_to: "29"
updated_at: 2010-12-16 10:25:28
project_id: "1"
current_estimate:
lft: "1"
original_estimate:
priority:
id: "10"
version_id:
area_id:
description:
worktype_id: "2"
status_id: "5"
rgt: "2"
parent_id:
created_at: 2010-05-21 07:37:15
fixed_in_version_id:
attributes_cache: {}
bulk attribute settings...
WARNING: Can't mass-assign these protected attributes: description
[4;36;1mIssue Load (0.0ms)[0m [0;1mSELECT "lft", "rgt", "parent_id" FROM "issues" WHERE ("issues"."id" = 10) [0m
after bulk settings
--- !ruby/object:Issue
area:
assigned_user:
attributes:
name: qqqqqqqqqq
assigned_to: "29"
updated_at: 2010-12-16 10:25:28
project_id: "1"
current_estimate:
lft: "1"
original_estimate:
priority:
id: "10"
version_id:
area_id:
description:
worktype_id: "2"
status_id: "5"
rgt: "2"
parent_id:
created_at: 2010-05-21 07:37:15
fixed_in_version_id:
attributes_cache: {}
changed_attributes: {}
children:
events:
fixed_in_version:
iterations:
marked_for_destruction: false
parent:
project:
status:
timelogs:
version:
work_items:
worktype:
[4;35;1mEvent Create (0.0ms)[0m [0mINSERT INTO "events" ("updated_at", "verb", "external", "issue_id", "note", "changes", "user_id", "created_at") VALUES('2010-12-16 10:33:08', 'Edited', 'f', 10, '', NULL, 1, '2010-12-16 10:33:08')[0m
after save
[4;36;1mEvent Load (16.0ms)[0m [0;1mSELECT * FROM "events" WHERE ("events".issue_id = 10) ORDER BY id ASC, created_at ASC[0m
--- &id001 !ruby/object:Issue
area:
assigned_user:
attributes:
name: qqqqqqqqqq
assigned_to: "29"
updated_at: 2010-12-16 10:25:28
project_id: "1"
current_estimate:
lft: "1"
original_estimate:
priority:
id: "10"
version_id:
area_id:
description:
worktype_id: "2"
status_id: "5"
rgt: "2"
parent_id:
created_at: 2010-05-21 07:37:15
fixed_in_version_id:
attributes_cache: {}
Technical info:
Op system: winXP
rails: rails 2.3.4
Additional info:
I have a bulk operation with the same purpose which is working correctly. I really don't know the differences:
def update_multiple
if params['cancel']
redirect_to issues_path
return
end
#issues = Issue.find(params[:issue_ids])
#issues.each do |issue|
issue.attributes= params[:issue].reject {|k,v| v.blank? }
issue.apply_template_on_name_change
issue.events.build(:note=>params[:issue][:description],:verb=>"Edited", :changes=>issue.textalize_changes)
issue.save!
end
flash[:notice]="Issues updated!"
redirect_to issues_path
end
Additional info:
If I replace #issue.attributes= params[:issue] by #issue.attributes= params[:issue].reject {|k,v| v.blank? } it apply changes and working. But it is not the one I really want. I want to change everything at once. I am going crazy.

Can you try save with exclamation, like #issue.save! to see the errors.

I have found the issue in awesome nested set.
This plugin reloads the object just before executing nested set operations.: I have changed the controller in the following way:
#issue.parent_issue= params[:issue][:parent_issue]
#issue.attributes= params[:issue].reject {|k,v| 'parent_issue'==k }
this the best solutions now.
note: parent_issue is for setting the parent of the given entity and using the same form as for the rest of the attributes.

Related

Extract records from Rails array

I have this variable in my pdforms_controller that is grouping all of the pdforms based on their group_id.
#groups = Pdform.where(principal_action: 'approved', super_action: 'new').group_by(&:group_id)
> {"DSC-002"=>[#<Pdform id: 63, date_start: "2017-12-08", date_finish: "2017-12-09", location: "First test", mtg_name: "First
> test", memo: "First test", acct_num: "12312312323", sub: true,
> accepted: false, guest_id: nil, created_at: "2017-12-08 21:36:37",
> updated_at: "2017-12-21 15:43:57", user_id: 13, pdtype:
> "instructional", reason: nil, prr_requested: nil, length: "full",
> principal_action: "approved", super_action: "new", group_id:
> "DSC-002", is_group: false>],
> "DSC-001"=>[#<Pdform id: 64, date_start: "2017-12-19", date_finish: "2017-12-20", location: "test", mtg_name: "test", memo:
> "test", acct_num: nil, sub: false, accepted: false, guest_id: nil,
> created_at: "2017-12-19 14:37:48", updated_at: "2017-12-20 18:05:55",
> user_id: 13, pdtype: "instructional", reason: "Dont like\r\n",
> prr_requested: nil, length: "half", principal_action: "approved",
> super_action: "new", group_id: "DSC-001", is_group: false>, #<Pdform
> id: 65, date_start: "2017-12-19", date_finish: "2017-12-20", location:
> "group test", mtg_name: "group test", memo: "group test", acct_num:
> "", sub: false, accepted: false, guest_id: nil, created_at:
> "2017-12-19 20:20:02", updated_at: "2017-12-21 15:50:21", user_id: 13,
> pdtype: "technology", reason: "wait, huh?", prr_requested: nil,
> length: "half", principal_action: "approved", super_action: "new",
> group_id: "DSC-001", is_group: false>]}
Right now I am just calling this in my view to display this information.
<%= #groups.each do |group| %>
<%-# do something -%>
<% end %>
How can I get each record out of this array and display that data in separate columns, bootstrap cards, or whatever other container I want to use? I have never used arrays to store data so excuse me if this is either blatantly obvious or a stupid question.
When you have a hash, like { key: 'value', other_key: 'other_value' }, you can use each as the following:
# in rails console
h = { some_key: 'value', other_key: 'other_value' }
h.each do |k, v|
puts "the value for key #{k.inspect} is #{v.inspect}"
end
# it will output:
the value for key :some_key is "value"
the value for key :other_key is "other_value"
So in your case, you can simply do:
#groups.each do |group_id, pdforms|
# group_id is the key (ex: "DSC-002")
# pdforms is the value for that key (in your case: an array of Pdform records)
# in this loop you can then cycle through all `pdforms`:
pdforms.each do |pdform|
# do something with a single Pdform record
end
end

Why do I receive undefined method after dynamically building array of Objects? Ruby

I'm building a most viewed post feature for a simple blog. Each post has a view count that is increased when the Show action is called for that particular post. Then on the Dashboard , I'm trying to list the top 5 posts. So far my code works and returns an array of posts with the post with the highest number of view count being the first index and the last index in the array being the post with the lowest view count. The only thing is when I try to iterate through the array in the view , the view returns:
ERROR
undefined method `title' for nil:NilClass
WHY??? Does it have to do with the "#" infront of the object?
Heres my code.
Dashboard View
<h3> Post </h3>
<% #top_posts.each do |post| %>
<%= post.title %>
<% end %>
Controller Methods
def get_top
#top_posts = []
counts = []
#posts = Post.all
#posts.each do |post|
counts << post.view_count
end
#posts.each do |post|
if counts.max(5).include?(post.view_count)
counts.max(5).each do |n|
if n == post.view_count
#top_posts[counts.max(5).index(n)] = post
end
end
end
end
end
def dashboard
#posts = Post.all
get_top
end
The Top Podcast Array of objects
[#<Post id: 6, title: "Post 6", desc: "", tags: "", view_count: 8, s_desc: "", c_photo: nil, photos: nil, created_at: "2017-06-14 06:02:25", updated_at: "2017-06-15 01:38:40", featured: nil>, #<Post id: 3, title: "post 3", desc: "", tags: "", view_count: 5, s_desc: "", c_photo: nil, photos: nil, created_at: "2017-06-14 05:35:32", updated_at: "2017-06-14 05:35:53", featured: nil>, #<Post id: 5, title: "Post 5", desc: "", tags: "", view_count: 4, s_desc: "", c_photo: nil, photos: nil, created_at: "2017-06-14 06:02:20", updated_at: "2017-06-15 01:38:31", featured: nil>, nil, #<Post id: 4, title: "Post 4", desc: "", tags: "", view_count: 3, s_desc: "", c_photo: nil, photos: nil, created_at: "2017-06-14 05:49:29", updated_at: "2017-06-15 01:38:50", featured: nil>]
The other answer would probably solve your error, but just want to make an attempt to optimize your code.
That array, loop, etc. is unnecessary, ask your db to do that stuff and get the top posts. Fetching all posts and looping over it multiple times...nay, try the following, hopefully this is what you are looking for..
#top_posts = Post.order('view_count desc').limit(5)
That's it, your view needs no change and will work as expected.
Try:
#top_posts << post
instead of:
#top_posts[counts.max(5).index(n)] = post
You don't need to set the array index.

Need help walking through nested hashes

Pardon my ignorance, I'm new to Ruby, but not programming. I'm using a gem called Ancestry to store hierarchical data in my application. They have a method called "descendants" that returns a nested hash of all the descending children, grandchildren, etc.. in a node, but I'm having a hard time trying to loop through each node and output all the child nodes.
Here's what the data structure looks like
{
#<Forum id: 16, name: "Parent 1", ancestry: "7", display_order: 1> =>{},
#<Forum id: 17, name: "Parent 2", ancestry: "7", display_order: 2> =>{},
#<Forum id: 13, name: "Parent 3", ancestry: "7", display_order: 3> =>
{
#<Forum id: 14, name: "Child 1", ancestry: "7/13", display_order: 1> =>{},
#<Forum id: 15, name: "Child 2", ancestry: "7/13", display_order: 2> =>
{
#<Forum id: 18, name: "Grand Child", ancestry: "7/13/15", display_order: 1> =>{},
}
}
}
When I loop through that data using the code below, the parent nodes are the only ones that end up being rendered to the screen.
<% forum.descendants.arrange(:order => :display_order).map do |forum,key| %>
<%= render :partial => 'forum', :locals => {:forum => forum} %>
<% end %>
How can I render the child nodes as well? I know they're accessible through the "key" variable, but I don't know how to tell when the "key" variable has data that I can render and how to output that data. Any suggestions?
You can check if the key is a hash by doing key.is_a?(Hash).
In your example, it will always evaluate to true because {} is an empty hash. You can check whether the hash is empty with key.empty?
To iterate through the nested hash, you can do it recursively something like this
def display hash
hash.each do |key, val|
# print key etc
if val.is_a?(Hash)
display val
else
# print value or whatever operation you want
end
end
end

Ruby on Rails: related models functional test error

I have been trying to figure out what is wrong with my test.
First, it works in the console.
The console:
1.9.2-p290 :015 > a = Allergy.all
Allergy Load (0.4ms) SELECT "allergies".* FROM "allergies"
=> [#<Allergy id: 1, name: "Milk", desc: "Allergic to milk", created_at: "2012-01-08 16:38:55", updated_at: "2012-01-09 11:48:20", patient_id: 1>, #<Allergy id: 2, name: "Blah", desc: "Test", created_at: "2012-01-09 12:20:48", updated_at: "2012-01-09 12:20:48", patient_id: 2>]
1.9.2-p290 :016 > a[0]
=> #<Allergy id: 1, name: "Milk", desc: "Allergic to milk", created_at: "2012-01-08 16:38:55", updated_at: "2012-01-09 11:48:20", patient_id: 1>
1.9.2-p290 :017 > a[0].patient.full_name
Patient Load (0.5ms) SELECT "patients".* FROM "patients" WHERE "patients"."id" = 1 LIMIT 1
=> "Test Full Name"
1.9.2-p290 :018 >
Allergy Controller
class AllergiesController < ApplicationController
# GET /allergies
# GET /allergies.json
def index
#allergies = Allergy.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #allergies }
end
end
# GET /allergies/1
# GET /allergies/1.json
def show
#allergy = Allergy.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #allergy }
end
end
...
Allergy Model
class Allergy < ActiveRecord::Base
validates :name, :presence => true
belongs_to :patient
end
Patient Model
class Patient < ActiveRecord::Base
validates :first_name, :last_name, :dob, :presence => true
has_many :allergies
def age
now = Time.now.utc.to_date
now.year - dob.year - ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? 0 : 1)
end
def full_name
first_name
end
end
The test:
require 'test_helper'
class AllergiesControllerTest < ActionController::TestCase
setup do
#allergy = allergies(:one)
#allergy.patient = patients(:one)
end
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:allergies)
end
...
The fixtures:
# For Allergy
one:
name: MyString
desc: MyText
patient_id: 1
two:
name: MyString
desc: MyText
patient_id: 1
#For Patient
one:
first_name: Jose
last_name: Rizal
middle_name: H
dob: 2009-10-29
two:
first_name: MyString
last_name: MyString
middle_name: MyString
dob: 1982-02-11
The error:
AllergiesControllerTest:
PASS should create allergy (0.22s)
PASS should destroy allergy (0.01s)
PASS should get edit (0.13s)
ERROR should get index (0.14s)
ActionView::Template::Error: undefined method `full_name' for nil:NilClass
/Users/wenbert/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.3/lib/active_support/whiny_nil.rb:48:in `method_missing'
PASS should get new (0.02s)
PASS should show allergy (0.02s)
PASS should update allergy (0.02s)
I have checked the logs and no Patient is saved when I run the test. I just get:
--- !ruby/object:Allergy
attributes:
id: 298486374
name: MyString
desc: MyText
created_at: 2012-01-09 14:28:21.000000000Z
updated_at: 2012-01-09 14:28:21.000000000Z
patient_id: 1
Patient Load (0.2ms) SELECT "patients".* FROM "patients" WHERE "patients"."id" = 1 LIMIT 1
--- !!null
...
So, what gives?
Any replies will be greatly appreciated. I have been stuck at this for almost 4 hours now. :(
Could it be my fixtures? My Models?
Best Regards,
W
FYI: I am using Ruby on Rails 3.1
Your fixtures have the same names, name them as following
allergy_one:
name: ...
patient: patient_one
allergy_two:
name: ...
patient_one:
name: ..
You will notice that I do not use patient_id in the fixtures. You need to reference the patient fixture you want as fixtures use random ids and do not start at 1.

How to populate select box from db query

I am trying to populate a ruby on rails select box from a database query, the data comes from 3 tables.
My query
#data = Session.all :include => { :term => :courses }
Object
!ruby/object:Session
attributes:
created_at: 2010-06-17 22:12:05
term_id: "15"
updated_at: 2010-06-17 22:12:05
id: "3"
course_id: "1"
attributes_cache: {}
term: &id003 !ruby/object:Term
attributes:
number: "1"
start_date: 2010-06-17
created_at: 2010-06-17 22:12:05
updated_at: 2010-06-17 22:12:05
id: "15"
attributes_cache: {}
courses:
- &id001 !ruby/object:Course
attributes:
created_at:
updated_at:
course_name: Beginner
id: "1"
date:
course_type: Programming
attributes_cache: {}
what i am trying to do is to have the term number followed by the data data and then the course
like this
1 01-09-10 Programming Beginners
The id for the option would be the session_id
any ideas ?
Thanks
Alex
in your erb template you can put the following code withing you form:
<%= select("session","id", #data.map{|d| ["#{d.term.number} #{d.term.start_date} #{d.course.course_type} #{d.course.course_name}",d.id]} %>

Resources