uninitialized constant ActionView::CompiledTemplates::BlogPost - ruby-on-rails

So I have the following in my blog_posts.rb model:
class BlogPost::Fetch < ActiveRecord::Base
API_URI = "http://blog.url.com/rss.xml".freeze
def class
posts = Rails.cache.fetch(API_URI, expires_in: 10.minutes) do
begin
feed = Feedjira::Feed.fetch_and_parse API_URI
feed.entries.take(2)
rescue
[]
end
end
posts
end
end
The following in my view helper:
module BlogHelper
def fetch_blog_posts(entries)
posts.each do |post|
unless exists? :guid => post.id
create!(
:title => post.title,
:pubDate => post.date
)
end
end
end
end
Then in my view:
<% BlogPost.fetch_blog_posts(2).each do |post| %>
<div class="home-blog-post">
<div class="news-date">
<%= post.display_date %>
With this present I end up with uninitialized constant ActionView::CompiledTemplates::BlogPost.
What am I missing? I feel like it's something simple that I'm just not seeing.
EDIT:
I have tried the following as well:
Added include ActiveRecord::Helpers in my model and changed the view to be BlogPost::Fetch. Same error
Put my helper method into the model and used both BlogPost::Fetch and BlogPost in the view. Same error for both.
Changed my model from inheriting from ActiveRecord::Base to Operator. Same error.
The only time I've gotten a different error is when I changed the model name to blog_post.rb and I get a circular error.
Another Edit:
I've pulled everything from the view helper as it's pointless. I'm not using a controller as it's in the CMS. So my model named fetch.rb now has the following:
class BlogPost::Fetch < ActiveRecord::Base
API_URI = 'http://blog.url.com/rss.xml'.freeze
def call
posts = Rails.cache.fetch(API_URI, expires_in: 10.minutes) do
begin
feed = Feedjira::Feed.fetch_and_parse API_URI
feed.entries.take(2)
rescue
[]
end
end
posts
end
def fetch_blog_posts
#posts = BlogPost::Fetch.run.result
end
end
Then in the view:
<% BlogPost.fetch_blog_posts(2).each do |post| %>
<div class="home-blog-post">
<div class="news-date">
<%= post.display_date %>
</div>
<%= link_to post.title, blog_post_path(post.url_name), class: 'news-title' %>
</div>
Still getting the same error.
So I tried changing my view to be:
<% #posts(2).each do |post| %>
<div class="home-blog-post">
<div class="news-date">
<%= post.display_date %>
</div>
<%= link_to post.title, blog_post_path(post.url_name), class: 'news-title' %>
</div>
In this case I end up with the error of: syntax error, unexpected '(', expecting keyword_end '.freeze; #posts(2).each do |post| ^

Took awhile but this worked. I changed the model to be:
class Fetch < ActiveRecord::Base
API_URI = 'http://blog.url.com/rss.xml'.freeze
def self.fetch_blog_posts(posts)
posts = Rails.cache.fetch(API_URI, expires_in: 10.minutes) do
begin
feed = Feedjira::Feed.fetch_and_parse API_URI
feed.entries.take(2)
rescue
[]
end
end
posts
end
end
Then updated the view to:
<% Fetch.fetch_blog_posts(2).each do |post| %>
<div class="home-blog-post">
<div class="news-date">
<%= post.published.strftime("%b %d, %Y") %>
</div>
<%= link_to post.title, post.url, class: 'news-title' %>

Related

Couldn't find a template file or inline render method for sub-component

Getting this error:
ViewComponent::TemplateError in Welcome#show
Couldn't find a template file or inline render method for FaqComponent::QuestionComponent.
Kind of stuck forever with this issue, not sure how to resolve it. Trying to render a simple component using view_component gem.
# app/components/faq_component.rb
class FaqComponent < ViewComponent::Base
renders_many :questions, "QuestionComponent"
class QuestionComponent < ViewComponent::Base
attr_reader :question
def initialize(question: "")
#question = question
end
end
end
Now, template file looks like:
file location: app/components/faq_component/faq_component.html.erb
<%= content_tag :div, class: "c-faq", data: { controller: "faq" } do %>
<%= content_tag :div, class: "c-card" do %>
<% questions.each do |q| %>
<%= content_tag :div, class: "c-card__section" do %>
<button class="c-faq__question" data-faq-target="question">
<%= q.question %>
<%= icon("arrow-expand", classes: "u-m-0", size: 12) %>
</button>
<div class="c-faq__answer">
<%= q %> <!- IT'S GETTING ERROR HERE ->
</div>
<% end %>
<% end %>
<% end %>
<% end %>
And finally trying to render here:
<div class="l-container u-mb-xxl u-xs-mb-l">
<div class="l-row">
<div class="l-col-xs-26 l-col-md-24 l-col-md-offset-1">
<h3 class="u-mb-s">Common Questions</h3>
<%= render(FaqComponent.new) do |faq| %>
<% faq.question(question: "What is ViewComponent?") do %>
<p>View component is a pain because it's not working or because I'm using it for the very first time!</p>
<% end %>
<% end %>
</div>
</div>
</div>
Any help will highly appreciable! :bow
Looks like you are inheriting class QuestionComponent from the wrong class, try inheriting it from ViewComponent::Base
# app/components/faq_component.rb
class FaqComponent < ViewComponent::Base
renders_many :questions, "QuestionComponent"
class QuestionComponent < ViewComponent::Base
attr_reader :question
def initialize(question: "")
#question = question
end
end
end
Have to define a template or call method for the QuestionComponent nested in the FaqComponent, that's the source of your errors.
That's why it fails at <%= q %>, which is trying to render the QuestionComponent. If you add a app/components/faq_component/question_component.html.erb file that would likely resolve the issue.
Maintainer replied here. Cheers!

Error with instance variable in Index view

So in my tutors_controller.rb this is my index action
def index
#tutor = Tutor.all
#tutor = #tutor.fees_search(params[:fees_search]) if params[:fees_search].present?
end
and in my index.html.erb this is the view
<div class='container'>
<%= form_tag(tutors_path, method: :get) do %>
<%= label_tag 'fees_search', 'Max Fees' %>
<%= select_tag 'fees_search', options_for_select((10..50).step(10)) %>
<%= submit_tag 'Filter' %>
<% end %>
<% #tutor.each do |tutor| %>
<% unless tutor.admin? %>
<div class='row' id='tutor-listing'>
<div class='col-xs-4'>
<%= image_tag(tutor.profile.avatar.url, :class => "img-rounded" ) if tutor.profile.avatar? %>
</div>
<div class='col-xs-8'>
<h3><%= link_to tutor.full_name, tutor_path(tutor) %></h3>
<% unless tutor.subjects.nil? %>
<% tutor.subjects.each do |subs| %>
<span class='badge'id='tutor-listing-badge'>
<%= link_to subs.name, subject_path(subs) %>
</span>
<% end %>
<% end %>
<% unless current_tutor %>
<%= button_to "Shortlist Tutor", add_to_cart_path(tutor.id), :method => :post %>
<% end %>
</div>
</div>
<% end %>
<% end %>
</div>
So i understand that when the index view first renders, #tutor would simply be Tutor.all so it renders each individual tutor perfectly.
After trying to filter it though, i start receiving errors. The exact error is NoMethodError in Tutors#indexand the highlighted line is <% unless tutor.admin? %>
profile.rb model
class Profile < ActiveRecord::Base
belongs_to :tutor
scope :fees_to, -> (fees_to) { where("fees_to <= ?", "#{fees_to}") }
end
tutor.rb model
class Tutor < ActiveRecord::Base
has_one :profile, dependent: :destroy
def self.fees_search(n)
#profile = Profile.fees_to(n)
if #profile.empty?
return Tutor.none
else
#profile.each do |y|
y.tutor
end
end
end
end
I get that now my #tutor instance variable has obviously changed. But how do i go about resolving this problem? Should i be rendering a partial instead? Obviously my index action in my controller could be "better" also but i'm quite confused now as to what i should be doing.
Would appreciate any advice! Thank you!
#profile.each do |y|
y.tutor
end
Seems to be a problem. All the other outcomes are a Tutor.something scope, whereas this will return the last tutor only. Change each to map to get an array of Tutors instead.

delayed_job_active_record - Undefined method `any?'

Attempting to send some stuff to the background with delayed_job_active_record, but how come I can't use any?? Works fine when things are not sent into the background.
undefined method `any?' for #<Delayed::Backend::ActiveRecord::Job:0x000000044b1348>
index.html.erb
<% if #products.any? %>
<div class="products">
<% #products.each do |product| %>
<%= product.name %>
<% end %>
</div>
<% else %>
<div class="products processing">
<!-- Try again later -->
</div>
<% end %>
main_controller.rb
class MainController < ApplicationController
def index
# Delay fetching
#products = Affiliate.delay.fetch
end
end
affiliate.rb
require "rest_client"
class Affiliate < ActiveRecord::Base
def self.fetch
response = RestClient::Request.execute(
:method => :get,
:url => "http://api.shopstyle.com/api/v2/products?pid=uid7849-6112293-28&fts=women&offset=0&limit=10"
)
#products = JSON.parse(response)["products"].map do |product|
product = OpenStruct.new(product)
affiliate = Affiliate.find_or_create_by(:name => product.name, :url => product.url)
affiliate.save
end
end
end
This doesn't work because #products isn't an array any more - it's a reference to a job that will get executed at some time in the future
You need a rethink of how your setup works. For example your view could poll via Ajax to see if the job has been completed. If it has then fetch the results from the DB, since you seem to be saving the API results there.

Rails 4 retrieve nested attributes for display in an index.html.erb

Just looking to find out how to retrieve nested images for display on my front page. I have no problems with a standard model but have been unable to find how to bring has_many nested attribute through. All my nested Forms work fine just have neglected the front end.
eg. product has nested product_images. This doesn't look like a clever way of doing it as the last five images uploaded wont necessarily be related to the last five products added.
Could someone please share an example.
cheers
app/controller/home_controller.rb
class HomeController < ApplicationController
def index
#products = Product.last(5)
#product_images = ProductImage.last(5)
end
end
app/views/home/index.html.erb
<% #products.each do |pd| %>
<div><%= pd.product_name %>
<% end %>
<% #product_images.each do |pd| %>
<%= image_tag (pd.product_image(:medium)) %>
<% end %>
</div>
You can try this:
app/controller/home_controller.rb
class HomeController < ApplicationController
def index
#products = Product.last(5)
#product_ids = #products.collect(:id)
#product_images = ProductImage.where(:id => #product_ids).last(5)
end
end
app/views/home/index.html.erb
<% #products.each do |pd| %>
<div><%= pd.product_name %>
<% end %>
<% #product_images.each do |pd| %>
<%= image_tag (pd.product_image(:medium)) %>
<% end %>

Link to remote destroy is not updating div

I created a view that show all my invoices products and also created a link that remove an invoice product from a div and it will be updated so everytime that I remove everything will be in the same page.
Here is the table
invoices
|id| |name|
1 ABC
2 DEF
invoice_products
|id| |invoice_id| |word|
1 1 AAAA
2 1 BBBB
3 2 CCCC
4 2 DDDD
Here is the controller:
def show
#invoice= Invoice.find(params[:id])
end
def destroy_job
#job = InvoiceProduct.find(params[:id])
#invoice = #job.invoice
#job.destroy()
render :partial=>"finance_management/invoice/partials/new_subjects" }
end
Here is the model
class Invoice < ActiveRecord::Base
has_many :invoice_products
end
class InvoiceProduct < ActiveRecord::Base
belongs_to :invoice
end
Here is the view: "show.html.erb"
<%= #invoice.id %>
<div id="table"%>
<% #invoice.invoice_products.each do |i| %>
<%= i.name %>
<%= i.word %>
<%=link_to_remote(image_tag("image.png"), :update => "table",:url => { :controller=>'finance_management/invoice_product',:action => 'destroy_job',:id=>i.id } )%>
<% end %>
</div>
The log:
ActionView::TemplateError (undefined method `invoice_products' for nil:NilClass)
I created "delete_job.js.erb":
$('table').html("<%= j(render partial: 'finance_management/invoice/partials/new_subjects') %>");
But I got this error:
NoMethodError (undefined method `invoice_products=' for nil:NilClass):
The problem is that is not updating the div seems because getting nil error
Somebody can help me please?
According to this you must do this:
The controller invoice_controller.rb:
def show
#invoice= Invoice.find(params[:id])
#products = InvoiceProduct.find(:all,:conditions=>['invoice_id = ?',params[:id] ])
end
def destroy_job
#job = InvoiceProduct.find(params[:id])
#obj_invoice = Invoice.find(#job.invoice_id)
#job.destroy
end
The view "invoice/show.html.erb"
<%= #invoice.id %>
<div id="table"%>
<%= render :partial=>"invoice/partials/products" %>
</div>
Don't forget to create the partial view "invoice/partials/_products.erb" this will replace the div
<% #products.each do |i| %>
<%= i.name %>
<%= i.word %>
<%=link_to_remote(image_tag("image.png"),:url=>{:controller=>'invoice',:action => 'destroy_job',:id=>i.id})%>
<% end %>
Finally create "invoice/destroy_job.rjs"
page.replace_html 'table', :partial=>'invoice/partials/products'
Create a file "destroy_job.js.erb" and place render method inside this file instead of calling it in controller:
$('YOUR_ID').html("<%= j(render partial: 'finance_management/invoice/partials/new_subjects') %>");

Resources