我有一个带有表单和表格的视图,可以显示数据库中的一些数据。每当我尝试在我的视图中从我的控制器访问该对象时,我得到undefined method domain for "https://www.lookagain.co.uk/":String
。但如果<%@savedHTML = ScrapedPage.all%>
一切正常。我知道我不应该在视图中这样做,因为它击败了MVC的目的,但我似乎没有完成修复。
查看:
<%= stylesheet_link_tag "masterstyles.css" %>
<% @url = 'default' %>
<%= form_for @url, :url => {:controller => "page_scraper", :action => "scrape"} do |f| %>
<%= f.text_field (:url) %>
<%= f.submit "Scrape" %>
<% end %>
<%@domain ='default'%>
<%@date ='default'%>
<%= form_for @domain, :url => {:controller => "page_scraper", :action => "compare"} do |f| %>
<%=select_tag 'domain', options_for_select(@savedHTML.collect{ |u| [u.domain, u.domain] })%>
<%=select_tag 'date', options_for_select(@savedHTML.collect{ |u| [u.created_at, u.created_at] })%>
<%= f.submit "compare" %>
<% end %>
<div class="subjects index">
<h2>FGH Page Scraper</h2>
<table class="listing" summary="Links list">
<tr class="header">
<th>ID</th>
<th>link</th>
<th>Created at</th>
<th>Updated at</th>
</tr>
<% @savedHTML.each do |page| %>
<tr>
<td><%= page.id %></td>
<td><%= page.domain %></td>
<td class="center"><%= page.created_at %></td>
<td class="center"><%= page.updated_at %></td>
<td class="actions">
<%= link_to("Delete", {:controller => 'page_scraper', :action => 'delete', :id => page.id}, :class => 'action delete') %>
</td>
</tr>
<% end %>
</table>
</div>
控制器:
class PageScraperController < ApplicationController
require 'nokogiri'
require 'open-uri'
require 'diffy'
require 'htmlentities'
def scrape
@url = watched_link_params[:url].to_s
puts "LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOG#{@url}"
@page = Nokogiri::HTML(open(@url))
coder = HTMLEntities.new
@encodedHTML = coder.encode(@page)
create
end
def index
@savedHTML = ScrapedPage.distinct.pluck(:domain)
end
def show
@savedHTML = ScrapedPage.distinct.pluck(:domain)
end
def new
@savedHTML = ScrapedPage.new
end
def create
@savedHTML = ScrapedPage.create(domain: @url, html: @encodedHTML, css: '', javascript: '')
if @savedHTML.save
puts "ADDED TO THE DATABASE"
redirect_to(root_path)
else
puts "FAILED TO ADD TO THE DATABASE"
end
end
def edit
end
def upadate
end
def delete
@savedHTML = ScrapedPage.find(params[:id])
end
def destroy
@savedHTML = ScrapedPage.find(params[:id])
@savedHTML.destroy
redirect_to(root_path)
end
def compare
@domain = params[:domain].to_s
puts @domain
redirect_to(root_path)
@timestamp
end
def watched_link_params
params.require(:default).permit(:url)
end
def compare_params
params.require(:domain).permit(:domain)
end
end
答案 0 :(得分:1)
问题在于,在控制器中,只将字符串值保存到@savedHTML
变量(pluck
只会给出给定对象的属性数组)。因此,您无法询问&#34; some_string&#34; .domain,因为String
类没有domain
方法。
如果domain
对象上有ScrapedPage
方法,那么在您的控制器操作(index
或show
- 无论您处理的是什么)中,您应该替换
@savedHTML = ScrapedPage.distinct.pluck(:domain)
与
@savedHTML = ScrapedPage.select(:domain).distinct
后者会根据ScrapedPage
值为您提供唯一的domain
个对象。请查看here以获取更多信息和示例。
NB!也是重构的提示:
在private
部分下使用强参数。此外,如果您在不同的操作中两次在控制器中使用相同的查询,那么最好在before_action中进行这样的查询:
class PageScraperController < ApplicationController
before_action :set_saved_html, only: %i[index show]
def index
end
def show
end
private
def watched_link_params
params.require(:default).permit(:url)
end
def compare_params
params.require(:domain).permit(:domain)
end
def set_saved_html
@savedHTML = ScrapedPage.select(:domain).distinct
end
end