This my first time asking a question so please go easy one me :-p
I am following the examples on http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials (Section 3.4.5 Rendering Collections) for rendering collections using partials. The code looks simple, but clearly I am missing something.
models/expert.rb contains the line:
attr_accessible :name
experts_controller.rb contains the following line in the index method:
#experts = Expert.all
views/experts/index.html.erb contains the following line:
<%= render :partial => "expert", :collection => #experts %>
views/experts/_expert.html.erb contains:
<%= expert.name %>
Upon viewing the index page in my browser I get the following error:
NoMethodError in Experts#index
undefined method `name' for nil:NilClass
I have been working on this for an hour and am completely stumped :-/ What little thing am I missing?
---Clarification---
Running '<%= debug #experts %>' within index.html.erb produces the following output:
- !ruby/object:Expert
attributes:
id: 1
name: Bob Smith
slug: bob-smith
created_at: '2012-03-11 18:37:11.791118'
updated_at: '2012-03-11 18:55:58.179629'
changed_attributes: {}
previously_changed: {}
attributes_cache: {}
marked_for_destruction: false
destroyed: false
readonly: false
new_record: false
- !ruby/object:Expert
attributes:
id: 2
name: Steve Kamp
slug: steve-kamp
created_at: !!null
updated_at: !!null
changed_attributes: {}
previously_changed: {}
attributes_cache: {}
marked_for_destruction: false
destroyed: false
readonly: false
new_record: false
The exception almost certainly means that there are no experts, so #experts is an empty array. Have you created any expert records yet?
Also, just so you'll know, to render a collection of objects the way you're doing there's a nice shortcut:
render #experts
Related
I three models Comment, User and Project. Project and Comment need to point to other objects in order to be valid. For example, a comment needs to point to an author (user) and a project.
The associated fixture files look like this:
# comments.yml
test_comment:
author: users(:test_user)
project: projects(:test_project)
# users.yml
test_user:
name: 'test user'
# projects.yml
test_project:
name: 'Test'
description: 'This is a test'
owner: users(:test_user)
However, I've found that my fixtures are probably set up incorrectly. Rails returns false if I try to save the comment:
assert_equal true, comments(:test_comment)
#=> false
I can see that there are foreign keys for a project and author:
=> #<Comment:0x00007f9b1661f3d8
id: 137725605,
body: "",
project_id: 745075726,
author_id: "31ceee04-5307-5059-91db-0dc2068a780c",
created_at: Fri, 22 Feb 2019 13:17:58 UTC +00:00,
updated_at: Fri, 22 Feb 2019 13:17:58 UTC +00:00>
But when I interrogate them, Rails returns nil.
> comments(:test_comment).author
=> nil
> comments(:test_comment).project
=> nil
I expected that one would return users(:test_user) and the other would return projects(:test_project). I thought perhaps I needed to use ERB in my yaml:
test_comment:
author: <%= users(:test_user) %>
project: <%= projects(:test_project) %>
But that results is a stream of errors when I run my tests:
NoMethodError: undefined method `users' for #<#<Class:0x00007f9b17692ff8>:0x00007f9b17692dc8>
What do I need to do to point fixtures to other fixtures? Can it be done? What have I done wrong?
In the Rails guide on Testing with YAML fixtures, you can see that you don't need users(:test_user) to refer to some other object. Instead, you can simply write test_user:
# comments.yml
test_comment:
author: test_user
project: test_project
# users.yml
test_user:
name: 'test user'
# projects.yml
test_project:
name: 'Test'
description: 'This is a test'
owner: test_user
Hope this helps!
I am displaying database data from a model called Show that has columns:
id: integer, title: string, show_date: date, description: text, ticket_cost: string, location: string, created_at: datetime, updated_at: datetime
The controller accesses each Show instance via:
#shows = Show.all.order(:show_date)
And the view displays the information using:
<% #shows.each do |show| %>
<h4><%= show.title %></h4>
<h5><span class="glyphicon glyphicon-map-marker"></span><%= show.location %></h5>
<h5><span class="glyphicon glyphicon-calendar"></span><%= show.show_date.to_formatted_s(:long_ordinal) %></h5>
<h5><span class="glyphicon glyphicon-usd"></span><%= show.ticket_cost %></h5>
<h5><%= show.description %></h5>
<% end %>
All of the show information (title, location, ticket_cost, description) is displaying on the view page but the date does not display, giving the error "undefined method `to_formatted_s' for nil:NilClass". Rails console shows date values for the show_date column so the value is not nil. Additionally, the shows are being ordered correctly by date, but the date itself will not display?
Edit: Added a line before show.title:
<%= debug show %>
Which displays debug information for each instance before printing the values to the screen. One instance does not have a date but all others do, and even for instances that have a non-nil date, the date is not displaying. An example of the debug information for one of the instances is:
--- !ruby/object:Show
raw_attributes:
id: 3
title: Show 3
show_date: 2017-03-05
description: Show 3 description
ticket_cost: "$3"
location: Show 3 location
created_at: &2 2017-02-05 21:19:15.000000000 Z
updated_at: &4 2017-02-05 21:19:15.000000000 Z
attributes: !ruby/object:ActiveRecord::AttributeSet
attributes: !ruby/object:ActiveRecord::LazyAttributeHash
delegate_hash:
id: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: id
value_before_type_cast: 3
type: !ruby/object:ActiveModel::Type::Integer
precision:
scale:
limit: 4
range: !ruby/range
begin: -2147483648
end: 2147483648
excl: true
original_attribute:
title: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: title
value_before_type_cast: Show 3
type: &1 !ruby/object:ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::MysqlString
precision:
scale:
limit: 255
original_attribute:
show_date: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: show_date
value_before_type_cast: 2017-03-05
type: !ruby/marshalable:ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter
:__v2__: []
[]: &3 !ruby/object:ActiveRecord::Type::DateTime
precision: 0
scale:
limit:
original_attribute:
description: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: description
value_before_type_cast: Show 3 description
type: !ruby/object:ActiveModel::Type::Text
precision:
scale:
limit: 65535
original_attribute:
ticket_cost: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: ticket_cost
value_before_type_cast: "$3"
type: *1
original_attribute:
location: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: location
value_before_type_cast: Show 3 location
type: *1
original_attribute:
created_at: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: created_at
value_before_type_cast: *2
type: !ruby/marshalable:ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter
:__v2__: []
[]: *3
original_attribute:
updated_at: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: updated_at
value_before_type_cast: *4
type: !ruby/marshalable:ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter
:__v2__: []
[]: *3
original_attribute:
new_record: false
active_record_yaml_version: 1
My guess is that sometimes your date really is nil... this can sometimes happen with old, test data hanging around. You can temporarily get around this by using try eg:
show.show_date.try(:to_formatted_s, :long_ordinal)
This will help you stop seeing this bug... and maybe get some more details of what is going on with your data that's causing the problem.
I'd also recommend adding some logging statements so you can see the data better (just while you're bugfixing)... eg:
<%= #shows.inspect %>
to see all the data you're getting and possibly spot the bad one.
I have been having issues with implementing multiple file upload with the carrierwave-mongoid gem. Multiple file upload with carrierwave is well documented for ActiveRecord but not Mongoid. I have tried to mirror the ActiveRecord tutorials are much as possible but cannot seem to get it right. My uploader is mounted as follows.
class Product
include Mongoid::Document
.....
attr_accessor :product_images, :product_images_cache
mount_uploaders :product_images, ProductImageUploader
end
The main issue that I am having is with saving the uploader instance. In my controller with a pry in the create block, I am able to create a Product instance that contains the uploader instances, but when I try to retrieve the Uploader instance via the rails console the array is empty. see below.
[22] pry(#<ProductsController>)> #product
=> #<Product _id: 58726dae75e505a9ddc43f20, name: "Post", description: "This is a post\r\n", rating: nil, category_id: 1, seller_id: 1, approved: false, approved_by: nil>
[23] pry(#<ProductsController>)> #product.product_images_urls
=> ["/uploads/tmp/1483894190-43485-0005-7191/download.jpeg", "/uploads/tmp/1483894190-43485-0006-6662/TRACK.jpg"]
[24] pry(#<ProductsController>)> Product.last
=> #<Product _id: 58726dae75e505a9ddc43f20, name: "Post", description: "This is a post\r\n", rating: nil, category_id: 1, seller_id: 1, approved: false, approved_by: nil>
[25] pry(#<ProductsController>)> Product.last.product_images_urls
=> []
What is notice here is that the images are not being save in the uploads directory. I have spent quite a bit of time researching this but no leads. Any help will be greatly appreciated.
Update: This method is currently not supported by CarrierWave-Mongoid. My initial thoughts where right the Uploader object was not being created/saved https://github.com/carrierwaveuploader/carrierwave-mongoid/issues/155. I am currently looking for a workaround for this - any pointer in this direction will be great
I asked a question earlier about calling associated model attributes.
Specifically, I asked about trying to display the names of the Vip model instances associated with an event.
Initially I had
<% #organization.events.each do |event| %>
<p>
<table>
<tr>
<td>
<%= event.name %>
</td>
<td>
<%= event.vips.name %>
</td>
</tr>
</table>
</p>
<% end %>
Which I changed to
<%= event.vips.first.name %>
and it worked for a little while. I eventually adjusted it to
<% event.vips.each do |vip| %>
<%= vip.name %>
which also worked for a little while. But when I came back to the computer after taking a break, new event form submissions were no longer displaying the vip's name on the organization show page, even though the database was being updated with the vip_id foreign key.
In fact, when I tried
<%= event.vips.first.name %>
again, I got an error saying "undefined method `name' for nil:NilClass"
I'm really not sure what changed, or what I'm doing wrong. So any help would be appreciated.
Update:
To help clarify the problem, I get the following outputs from the console:
irb(main):005:0> Event.first
Event Load (0.2ms) SELECT "events".* FROM "events" ORDER BY "events"."id" ASC LIMIT 1
=> #<Event id: 1, when: "2015-08-25 00:00:00", organization_id: 1, created_at: "2015-08-25 04:47:43", updated_at: "2015-08-25 04:47:43", name: "John's Event", vip_id: 1>
irb(main):006:0> Vip.first
Vip Load (0.2ms) SELECT "vips".* FROM "vips" ORDER BY "vips"."id" ASC LIMIT 1
=> #<Vip id: 1, name: "John", created_at: "2015-08-25 04:46:23", updated_at: "2015-08-25 04:46:23", organization_id: 1, event_id: nil>
irb(main):007:0> #organization
=> #<Organization id: 1, name: "Test Org", created_at: "2015-08-25 04:46:03", updated_at: "2015-08-25 04:46:03", user_id: 1>
irb(main):008:0> #organization.events.first
=> #<Event id: 1, when: "2015-08-25 00:00:00", organization_id: 1, created_at: "2015-08-25 04:47:43", updated_at: "2015-08-25 04:47:43", name: "John's Event", vip_id: 1>
irb(main):009:0> #organization.events.first.vips
Vip Load (0.2ms) SELECT "vips".* FROM "vips" WHERE "vips"."event_id" = ? [["event_id", 1]]
=> #<ActiveRecord::Associations::CollectionProxy []>
irb(main):010:0>
Your event has no vips. Since event.vips is basically an empty array, calling #first on it returns nil. You then try to call #name on nil. But #name isn't a method of nil, hence the error undefined method 'name' for nil:NilClass.
Normally,
event.vips.first.name will return the error you received if event.vips.first is Nil (which just means that that specific event has no vips, because .first returned Nil or nothing).
In some other times however event.vips.first is a Vip record (which just means that that specific event has at least one Vip).
Since in my first Scenario it returned nil, then nil.name will obviously return an error. However, in my second scenario that it retuned vip, then vip.name will now work as you were expecting it to be.
You may try this if you want to disregard the error being raised: event.vips.first.try(:name)
Your code will work if update the event_id of vip
Vip.first.update_attribute event_id, Event.first.id
Issue happen because we don't have an association between Event.first and Vip.first
btw, I don't think we should use event.vips.first.name because vips can be empty
We can change it a little, ex:
event.vips.first.try(:name)
or
event.vips.map(&:name).join(", ")
I have this object y my database:
=> #<Page _id: 50683d421d41c8363d000060, _type: nil, created_at: 2012-09-30 12:38:26 UTC, title: "Terms", description: "Terms of use... <b>description</b>", published: true, slug: "terms">
On description field I have added with https://github.com/Nerian/bootstrap-wysihtml5-rails a b tag for bold.
But When I render my page I can see:
Terms of use... <b>description</b>
How can I render html tags on my mongodb database data?
Preview
http://www.image-share.com/ijpg-1766-71.html
Rails escapes html by default for security's sake.
When you trust content, tell Rails:
<%= raw your_variable %>
Or:
<%= your_variable.html_safe %>