I am trying to make an app with Rails 4.
I have installed the public_activity gem.
I followed the Ryan Bates Railscast and took the controller based approach, and also the lighter Common option (as opposed to tracking the Model).
In my activities_controller I have:
class ActivitiesController < ApplicationController
def index
#activities = PublicActivity::Activity.order("created_at desc")
end
end
In my project.rb, I have:
include PublicActivity::Common
In my projects controller, create action, I have:
#project.create_activity :create, owner: current_user
In my activity view - index, I have:
<% Activities.each do |activity| %>
<div class="col-md-4">
<div class="indexdisplay">
<span class="indexheading">
<%= link_to activity.owner.name, activity.owner if activity.owner %>
</span>
<span class="indexsubtext">
<%= render_activity activity %>
</span>
In my public activity (view folder)/project/_create.html.erb, I have:
<% if activity.trackable %>
<%= link_to activity.trackable.name, activity.trackable %>
<% else %>
which has since been removed
<% end %>
When I try this, I get this error:
NameError at /activities
uninitialized constant ActionView::CompiledTemplates::Activities
I tried replacing the opening line of the activity#index so that Activities, is Activity, but it just changed the error message to:
NameError at /activities
uninitialized constant ActionView::CompiledTemplates::Activities
What does this error mean? How do I fix it?
Thank you
It seems like you use Class in your loop. Try to use your instance variable in your controller.
Change this
<% Activities.each do |activity| %>
into
<% #activities.each do |activity| %>
It should be <% Activity.find_each do |activity| %>
Model name always is singular
You cannot call each just on Model
I'd recommend you use find_each instead of each in case you have a lot of records
if you do want all the records you can always use .all method
http://apidock.com/rails/ActiveRecord/Batches/ClassMethods/find_each
Related
I'm using the acts_as_votable gem to like and unlike "Deals" in my Ruby on Rails project. My user is set to act_as_voter and my deal is set to acts_as_votable, but for some reason everything is set to like as soon as a new user is created, and they can't unlike the deal. For some reason my list of deals all have an unlike button and it doesn't actually do anything but refresh the page. Here's some of my code.
app/views/catalog/index.html.erb
<ul class="deals_list">
<% #deals.each do |deal| %>
<li>
<div>
...
<div class="favorite">
<% if account_signed_in? and current_account.accountable_type == "Personnel" %>
<%= image_tag("dark-favorite.png") %>
<% if deal.liked_by current_account %>
<%= link_to unlike_deal_path(deal), method: :put do %>
Unlike
<% end %>
<% else %>
<%= link_to like_deal_path(deal), method: :put do %>
Like
<% end %>
<% end %>
<% end %>
</div>
</li>
<% end %>
</ul>
app/controllers/deals_controller.rb
def like
#deal = Deal.find(params[:id])
#deal.liked_by current_account
redirect_back(fallback_location: catalog_index_url)
end
def unlike
#deal = Deal.find(params[:id])
#deal.unliked_by current_account
redirect_back(fallback_location: catalog_index_url)
end
config/routes.rb
resources :deals do
member do
put 'like', to: "deals#like"
put 'unlike', to: "deals#unlike"
end
end
Be sure and read the entire Readme because you're using the library wrong.
To check if a voter has voted on a model, you can use voted_for?. You can check how the voter voted by using voted_as_when_voted_for.
I zeroed in on your problem because I was expecting to see a "?" after the deal.liked_by call, which would indicate a boolean result (by convention, not always the case).
So use this instead:
<% if current_account.voted_for? deal %>
I'm having trouble with using link_to in Ruby on Rails. I'm making a blog like application which displays a feed of all user posts and allows users to click posts to view/edit them.
This is my _feed partial, which is used to render all the posts of a user.
<% if #feed_items.any? %>
<% #feed_items.in_groups_of(3, false).each do |feeds| %>
<div class="row">
<% feeds.each do |feed| %>
<div class="col-md-4">
<ol class="posts">
<%= link_to render feed , edit_post_path(feed) %>
</ol>
</div>
<% end %>
</div>
<% end %>
<% end %>
The line <%= link_to render feed , edit_post_path(feed) %> is what is throwing errors. I'm just not 100% certain how to write a link_to which also renders the feed. I've tried a lot of variations and nothing works. The error I get as it is currently written is: undefined method `keys' for "/posts/160/edit":String
This is my Posts controller, which I wrote after this error occurred in an attempt to fix it. I'm not sure if any of this is even necessary:
class PostsController < ApplicationController
before_action :find_note, only: [:show, :edit]
def edit
end
def show
end
private
def find_note
#post = Post.find(params[:id])
end
I'm sure my problem is super basic but I'm having trouble figuring out how to solve it. Any help is appreciated!
Use block to render a partial inside of a link:
<%= link_to edit_post_path(feed) do %>
<%= render feed %>
<% end %>
I have a main page that is currently static and I also have a group of pages that I generated from a scaffold.
I would like to add the embedded ruby objects from the scaffold to the main page. I'm not sure if I have to do something with the controller, models, or the routes.
For example: <% #projects.title %> on my main page. As of now I receive the NoMethodError Undefined Method. Which I get, but I'm stuck as to how to troubleshoot.
Is this possible?
Thanks.
You have either ways...
1st is to load instance variable through your static pages controller
..app/controllers/staticPages.rb
class StaticPagesController < ApplicationController
...
def mainPage
#projects = Project.all
end
...
end
Then you iterate over this collection in your view using something like the following
..app/views/static_pages/main.html.erb
<% #projects.each do |project| %>
<div>
...
<p><%= project.name %></p>
<p><%= project.other_stuff %></p>
...
</div>
<% end %>
Or you can just load the collection from your view
..app/views/static_pages/main.html.erb
<% Project.all.each do |project| %>
<div>
...
<p><%= project.name %></p>
<p><%= project.other_stuff %></p>
...
</div>
<% end %>
I'm new to rails and I'm trying to build a view that will list the parents and related children
Ex:
Passport has many Visas
I want to list information about the passport and the visas that the passport has.
So I have
<% #passport_list.each do |passport| %>
# passportFields
<% passport.visas.each do |visa| %>
<%= t.text_field :visa_type %>
<% end %>
<% end %>
I'm getting the error
undefined method `visa_type' for #Passport:0x000000091b8b28
It looks like rails is trying to find the property visa_type for passport, instead of in visa. How does the scope work within each? Can I force it to access visa_type from visa?
I think you're looking for the fields_for form helper. This will allow you to create fields for the relevant visa attributes. Replace your code sample with the following, and you should be all set.
<% #passport_list.each do |passport| %>
# passportFields
<% t.fields_for :visas do |visa_fields| %>
<%= visa_fields.text_field :visa_type %>
<% end %>
<% end %>
You can also iterate over the list as follows:
<% #passport_list.each do |passport| %>
# passportFields
<% passport.visas.each do |visa| %>
<% t.fields_for :visas do |visa_fields| %>
<%= visa_fields.text_field :visa_type %>
<% end %>
<% end %>
<% end %>
For more information on fields_for, check out the link I added above, and to customize further for your use case, check out the "One-to-many" section.
IMO you should always handle the null case of an object.
Something like this if you use rails (present? is a Rails function)...
<% if #passport_list.present? %>
<% #passport_list.each do |passport| %>
passportFields
<% passport.visas.each do |visa| %>
<%= t.text_field :visa_type %>
<%end%>
<%end%>
<% else %>
<p>Nothing to see here</p>
<% end %>
However if your #passport_list is backed by an ActiveRecord Query, you can handle this in the model/helper/controller by returning the .none query on the model. Note that this differs from an empty array because it is an ActiveRecord Scope, so you can chain AR queries onto it
# scope on AR model
def self.awesomeville
where(country_of_origin: "awesomeville")
end
# method queried in controller
#passport_list = Passport.all
if #passport_list.present?
#passport_list
else
Passport.none
end
# additional filtering in view is now possible without fear of NoMethodError
#passport_list.awesomeville
Whereas a ruby Array would raise an error as it would respond to the Array methods.
/products/index.html.erb
<div class="hide-for-small panel">
<h3>Sidebar</h3>
<h5 class="subheader">Feature Product</h5>
<% Product.random do | product | %>
<%= image_tag(Product.image_url) %>
<h5><%= link_to Product.title, product %></h5>
<p><%= button_to 'Add to Cart', line_items_path(:product_id => product) %></p>
<% end %>
</div>
/models/product.rb
def Product.random
self.limit(1).offset(rand(self.count)).first
end
Trying to pull a random product using Postgres. The query comes through in the console but I get no view results in the index.
Any solutions or different ways of accomplishing this?
The whole issue is you're passing a block to a method that doesn't take a block, so its silently ignored, and never executed, so the other problems you have don't come up.
All of your code sits inside a block which you're passing to Product.random via Product.random do |product|. That should be product = Product.random with no do/end block.
Once you've done this, you'll start seeing more errors as you're using Product.title instead of product.title etc.
It looks like your product in your image_tag and link are incorrectly referencing the model and not the random one.
Try changing these:
<%= image_tag(product.image_url) %>
<h5><%= link_to product.title, product %></h5>
You should really generate the random product in your controller and access an instance variable in your view.
Something like:
controller's index action:
#random_product = Product.random
view:
<%= image_tag(#random_product.image_url) %>
etc.
You should never access the model directly from the view.
First of all, you're mixing up class methods with instance methods. Try making the view:
<div class="hide-for-small panel">
<h3>Sidebar</h3>
<h5 class="subheader">Feature Product</h5>
<%= image_tag(#product.image_url) %>
<h5><%= link_to #product.title, #product %></h5>
<p><%= button_to 'Add to Cart', line_items_path(:product_id => #product.id) %></p>
</div>
Class methods (Product.random) are defined when you don't need a specific one. So product.title if for a specific product.
Second of all, in your controller for this action, you'll need to define the #product instance variable as #product = Product.random. And then you can use that in the view.
Third of all, getting a random record could be simplified to:
Product.order("RANDOM()").first
So your model code would look like:
def self.random
Product.order("RANDOM()").first
end