Weird problem: collection object displaying in view? - ruby-on-rails-3

When I run the following code in the view:
- if #object.winner.present? && #object.winner.prizes.any?
%ul
= #object.winner.prizes.each do |p|
%li= p.description.html_safe
It's returning this:
li prize1
li prize2
li prize3
...
[#<Prize object...> ... ]
Does anyone know why it is listing the #object.winner.prizes collection in the view directly after the last #object.winner.prizes object is displayed?
Extremely baffled! I'm using Rails v3.0.6

This is because you're using = when you should be using - to iterate over the objects:
- #object.winner.prizes.each do |p|

Related

How to pass a singleton object to a partial in rails?

I have the following code in my controller
#current_chat = current_user.sent_messages
.where("created_at > ? and receiver_id = ?", current_user.current_sign_in_at, current_chat[:receiver_id].to_i)
.select("body, created_at").each { |message| message.instance_eval { def type; #type end; #type = 'sent' } }
And I'm passing the #current_chat object to a partial like so:
<%= render partial: 'shared/chat_form', locals: { messages: #current_chat } %>
But I'm getting the following error:
singleton can't be dumped
At the first line in ActiveSupport::MessageVerifier#generate
def generate(value)
data = ::Base64.strict_encode64(#serializer.dump(value))
"#{data}--#{generate_digest(data)}"
end
Any ideas on how to fix this?. Thanks in advance.
You can not use this
#serializer.dump(value)
This is causing the error. Read this link, its all about using singletons in ruby.
link

including rails object in meta tags keywords

I'd like to include a rails object in my keywords as well as straight text but the code is clearly not the right way to do it...how can I do this?
set_meta_tags :keywords => %w[keyword1 keyword2 #{params[:hospital]}]
You might want to have a look at two plug-ins for including rails object in meta tags:
Meta Magic: https://github.com/lassebunk/metamagic
Head Liner: https://github.com/mokolabs/headliner
Edit: For Meta tag gem
What I usually do is write a meta helper that I simply stick in my ApplicationHelper, that looks like this:
def meta(field = nil, list = [])
field = field.to_s
#meta ||= {
'robots' => ['all'],
'copyright' => ['My Copyright'],
'content-language' => ['en'],
'title' => [],
'keywords' => []
}
if field.present?
#meta[field] ||= []
case list.class
when Array then
#meta[field] += list
when String then
#meta[field] += [list]
else
#meta[field] += [list]
end
case field
when 'description' then
content = truncate(strip_tags(h(#meta[field].join(', '))), :length => 255)
else
content = #meta[field].join(', ')
end
return raw(%(<meta #{att}="#{h(field)}" content="#{h(content)}"/>))
else
tags = ''
#meta.each do |field, list|
tags += meta(field)+"\n"
end
return tags.rstrip
end
end
You can simply set meta tags in your views, by adding a call to meta() in it. So in an articles/show.html.erb you might add this to the top of your view:
<% meta(:title, #article.title) %>
And in your layouts, you add it without any parameters, so it'll spit out the meta tags.
<%= meta %>
Or have it output an individual tag:
<%= meta(:title) %>
I bet you there's more elegant solutions, though.
But if you were looking for something already implemented in Rails you're out of luck.
Thanks.
Try this in your view as it worked for me (using meta-tags gem):
<% keywords [[#modelname.keyword1], [#modelname.keyword2]] %>
and you cad additional keywords in text format by adding them within the ruby in the following format ['keyword3']

Access a query in Ruby on Rails

I have in my controller this:
#itemsok = Search.where("first_item_id = ?", params["3"])
This is sopposed to be a query in the search table of the database asking for all the searches that have a first_item_id = 3 ...
Question 1 .- The syntax is I found it in http://guides.rubyonrails.org/active_record_querying.html but im not sure if im using it right?
Ok the question 2 is, I have this on the controller, is it ok to have querys in the controller?
In the view im printing the variable <%= #itemsok %> and all I get is a
ActiveRecord::Relation:0x007fd3d3e894d8
Any suggestions?
Thanks in advance.
ActiveRecord 3 lets you chain relations together so you can do something like this:
#itemsok = Search.where("first_item_id = ?", params["3"]).where("foo = ?", "bar")
The where() function returns an ActiveRecord::Relation. Generally this isn't a problem, since if you use the object it'll automatically run the query and return the results on the object so you'll get the database objects. AR doesn't run the query until it's actually needed.
Where will return a list of items (Array), so if you're just debugging, change your view to this:
<%= debug #itemsok.to_a %>
You seem to be constructing the query wrong way.
If you want to search for records with first_item_id = 3, you should do:
Search.where("first_item_id = ?", 3)
This will return an array of matching records, something you can't easily print with <%= #itemsok %>. You should iterate over the elements and print each one:
<% #itemsok.each do |item| %>
<%= item.name %>
<% end %>
I'd also suggest defining to_s method for the objects you want to print.
class Search
def to_s
name
end
end
Then you can simply print the object and to_s method will be automatically called for you:
<% #itemsok.each do |item| %>
<%= item %>
<% end %>
The right way to do is to define a namedscope in the model and then use it in the controller.
Something similar to this :
class Search < ActiveRecord::Base
named_scope:item_ok,lambda {|*args|{:conditions=>["item_id >= ?", args.first]}}
end
and then call the namedscope from the controller like this :
#itemsok = Search.item_ok(params[:value])

Rails filtering with acts_as_taggable gem

I am working the acts-as-taggable-on gem and have a question about how to filter down search results based on tags users select. Here's an abridged look at my controller:
class PhotosController < ApplicationController
def index
#photos = Photo.where(["created_at > ? AND is_approved = ?", 1.months.ago, true])
#tags = ["Animals", "Architecture", "Cars", "Flowers", "Food/Drink", "General", "Landscape", "Mountains", "Nature"]
end
def search_by_tag(tag)
#photos = Photo.where('tagged_with LIKE ?', tag)
end
end
Photos/index
<% #tags.each do |tag| %>
<%= link_to tag, {:search_by_tag => tag}, :class => "tag" %>
<% end %>
This lists out all of the tags from the hash #tags defined in index, but clicking them doesn't actually filter anything down. Here's a look at what clicking one of those links produces in the log:
Started GET "/photos?search_by_tag=Animals" for 127.0.0.1 at Sun Oct 09 17:11:09 -0400 2011
Processing by PhotosController#index as HTML
Parameters: {"search_by_tag"=>"Animals"}
SQL (0.5ms) SELECT name FROM sqlite_master WHERE type = 'table' AND NOT name = 'sqlite_sequence'
The result I want is for the page to display only Photos that are tagged_with whichever tag was clicked on. I can't quite figure out how to accomplish this.
(Side-question: I can't seem to find a way to list out all of the tags from the tags table that acts-as-taggable-on generated. Doing something like Photo.tagged_with or Photo.tags doesn't work. I am able to see the "tags" table the gem created, and the entries inside of it; I'm just not really clear how to handle that using this gem)
Any thoughts greatly appreciated.
UPDATE
I've updated my code and am a bit closer.
class PhotosController < ApplicationController
def search_by_tag
#photos = Photo.tagged_with(params[:tag_name])
end
photos/index
<% Photo.tag_counts_on(:tags).map(&:name).each do |tag| %>
<%= link_to tag, {:action => 'search_by_tag', :tag_name => tag}, :class => "tag" %>
<% end %>
I believe this is closer, but still working through this...
You have a number of errors in your code:
Your link_to call is actually calling the index action.
Your search_by_tag method is expecting an argument, where it should be using the params hash to access the parameters passed to it in the web request.
tagged_with is a class method added by acts_as_taggable_on, not a field in your table - therefore you can't use it in the where method like you have done.
Finally, to get all the tag names: Photo.tag_counts_on(:tags_or_whatever_you_tagged_on).map(&:name)
Take a look at the acts_as_taggable_on documentation and you'll see examples of how to use tag_counts_on and tagged_with.
As for the Rails things: http://guides.rubyonrails.org/ http://railsforzombies.org/ and/or http://railscasts.com/

Rails 3 noob - difficulty populating an array

UPDATED WITH SOLUTION FROM BELOW PRODUCES NEW ERROR.
Users invite others to review their work. To track this, the invitations table has reviewer_id and reviewee_id fields. The model contains:
belongs_to :user
has_many :users
To display all invitations for a user we first get all the invitations:
#invitations = Invitation.where("reviewee_id = ?", current_user.id ).select(:reviewer_id).order("updated_at")
Then we get all the users who were invited: (this part is wrong)
#reviewers = []
#invitations.each do |i|
#reviewers << User.where("id = ?", i.reviewer_id )
end
This current solution produces the following:
undefined method `first_name' for []:ActiveRecord::Relation
I did a test with the following code to see what is in #reviewers:
<% #reviewers.each do |r| %>
<%= r.id %><br>
<% end %>
Instead of returning the ids it returned:
2173491700
2173491200
2173490540
So the array is not getting populated appropriately.
I am grateful for your help and most grateful for specific code.
You want to gather up all the IDs then pass them to where.
reviewer_ids = #invitations.collect { |i| i.reviewer_id }
#reviewers = User.where(:id => reviewer_ids)
This grabs all the reviewers in a single database call.
Do the following to get the reviewers:
#reviewers = []
#invitations.each do |i|
#reviewers << User.where("id = ?", i.reviewer_id )
end
The << adds elements to the array. And, before the iteration we create an array.