How to populate select box from db query - ruby-on-rails

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]} %>

Related

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.

Compare two arrays using include?

I have two arrays:
#all_genres = [#<Genre id: 1, name: "Action", created_at: "2013-03-01 07:44:51", updated_at: "2013-03-01 07:44:51">,
#<Genre id: 2, name: "Adventure", created_at: "2013-03-01 07:44:51", updated_at: "2013-03-01 07:44:51">,
#<Genre id: 3, name: "Animation", created_at: "2013-03-01 07:44:51", updated_at: "2013-03-01 07:44:51">]
#genres = ["Action", "Animation"]
I am trying to find the Genre.id from #genres compared to the #all_genres table. For example my result should be:
#genre_ids = [1, 3]
I have tried this:
#all_genres.each do |g|
if g.name.include?((#genres.each {|g| g}).to_s)
#genre_ids << g.id
end
end
I tried this in my console and it seemed to work but when I put it into my app it returns:
#genre_ids = []
A more rail-sy version:
#genre_ids = Genre.where(name: #genres).pluck(:id)
Or you could try this one-liner:
#genre_ids = #all_genres.select{|g| #genres.include? g.name }.map(&:id)
I'm assuming that you're populating your #genres array with a call to Genre.all.
You could simply do something like this:
Genre.where("name IN (?)", %w[name action]).collect { |x| x.id }
If you want to retrieve the ids for the Genres with those names.

to_json skips attributes with nil value

hi i am new to ruby on rails and using mongoid with rails.
when i try to convert an mongoid object into json the attributes with nil values are skipped.
ruby-1.9.2-p180 :019 >#task
=> #<Task _id: 4e707635c7b4700ce3000004, _type: "Task", created_at: 2011-09-14 09:39:01 UTC, updated_at: 2011-09-14 09:39:01 UTC, due_date: nil, is_completed: false, assignee_id: nil, description: "hi remind this ", user_id: BSON::ObjectId('4e4d1aeac7b4700c6e000096'), item_id: BSON::ObjectId('4e53585fc7b4701082000002')>
#task.to_json(:only=>[:due_date])
=> "{}"
is there any way to get like "{\"due_date\":\"null\"}"
The easiest way to do this is to override the retrieval of due_date.
Try this in your model:
def due_date
real_value = self[:due_date]
return real_value unless real_value.nil?
return "null"
end

Attribute changes are not notified and table is not updated

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.

looping and casting problem in rails

I've got following method in User model
def get_employees
#employees = []
groups.each do |i|
#employees << Group.find(i).employees
end
#employees
end
This is what the console prints when I call this method:
> >> User.find(4).get_employees
> => [[#<Employee id: 4, first_name: "test", last_name: "test1",
> email_address: "test#gmail.com",
> created_at: "2010-08-25 04:23:02",
> updated_at: "2010-08-25 04:23:02">,
> #<Employee id: 5, first_name: "hello", last_name: "hello1", email_address:
> "hello#gmail.com", created_at:
> "2010-08-25 04:51:37", updated_at:
> "2010-08-25 04:51:37">]]
however, the following code does not work:
>> #user.get_employees.each{|i| p i.first_name}
NoMethodError: undefined method `first_name' for #<Class:0x9e372f0>
What do I need to do in order to get the first_name of the employees from the loop?
The Group.find(i).employees call returns an array, so your get_employees method is returning an array of arrays. Replacing the last line of get_employees with #employees.flatten! should do the trick.
Looks to me that the variable i is still an array. You declare #employee as an empty array and you insert another array which is what is returned by Group.find(i).employees.
i[0] should contain:
#<Employee id: 4, first_name: "test", last_name: "test1",
> email_address: "test#gmail.com",
> created_at: "2010-08-25 04:23:02",
> updated_at: "2010-08-25 04:23:02">,
> #<Employee id: 5, first_name: "hello", last_name: "hello1", email_address:
> "hello#gmail.com", created_at:
> "2010-08-25 04:51:37", updated_at:
> "2010-08-25 04:51:37">
As the previous poster noted, you've got an array within an array. Why recreate some logic that is already built into rails? I would have done something like this in the user model:
class User < ActiveRecord::Base
has_many :groups
has_many :employees, :through => :groups
end
Then you can just do User.employees

Resources