Reputation: 211
I am trying to do a search in the spree backend in reviews listing page.
But am getting undefined method error for the fields. Eg: undefined method title_cont' , undefined method
review _cont'.
Hereby am posting my controller:
reviews_controller.rb
class Spree::Admin::ReviewsController < Spree::Admin::ResourceController
helper Spree::ReviewsHelper
def index
@reviews = Spree::Review.ransack(params[:q]).result
end
def approve
r = Spree::Review.find(params[:id])
if r.update_attribute(:approved, true)
flash[:notice] = Spree.t("info_approve_review")
else
flash[:error] = Spree.t("error_approve_review")
end
redirect_to admin_reviews_path
end
def edit
if @review.product.nil?
flash[:error] = Spree.t("error_no_product")
redirect_to admin_reviews_path and return
end
end
private
def collection
params[:q] ||= {}
@search = Spree::Review.ransack(params[:q])
@collection = @search.result.includes([:product, :user, :feedback_reviews]).page(params[:page]).per(params[:per_page])
end
end
Model File : review.rb
class Spree::Review < ActiveRecord::Base
belongs_to :product, touch: true
belongs_to :user, :class_name => Spree.user_class.to_s
has_many :feedback_reviews
after_save :recalculate_product_rating, :if => :approved?
after_destroy :recalculate_product_rating
validates :name, presence: true
validates :review, presence: true
validates :rating, numericality: { only_integer: true,
greater_than_or_equal_to: 1,
less_than_or_equal_to: 5,
message: Spree.t('you_must_enter_value_for_rating') }
default_scope { order("spree_reviews.created_at DESC") }
scope :localized, ->(lc) { where('spree_reviews.locale = ?', lc) }
scope :most_recent_first, -> { order('spree_reviews.created_at DESC') }
scope :oldest_first, -> { reorder('spree_reviews.created_at ASC') }
scope :preview, -> { limit(Spree::Reviews::Config[:preview_size]).oldest_first }
scope :approved, -> { where(approved: true) }
scope :not_approved, -> { where(approved: false) }
scope :default_approval_filter, -> { Spree::Reviews::Config[:include_unapproved_reviews] ? all : approved }
def feedback_stars
return 0 if feedback_reviews.size <= 0
((feedback_reviews.sum(:rating) / feedback_reviews.size) + 0.5).floor
end
def set_search
@search=Product.search(params[:q])
end
def recalculate_product_rating
self.product.recalculate_rating if product.present?
end
end
Index.html.erb
<% content_for :table_filter do %>
<div data-hook="admin_reviews_index_search">
<%= search_form_for [:admin, @search] do |f| %>
<div class="alpha three columns">
<div class="field">
<%= label_tag nil, Spree.t(:user) %><br />
<%= f.text_field :name_cont,:size => 25 %>
</div>
</div>
<div class="four columns">
<div class="field">
<%= label_tag nil, Spree.t(:title) -%><br/>
<%= f.text_field :title_cont, :size => 25%>
</div>
</div>
<div class="four columns">
<div class="field">
<%= label_tag nil, Spree.t(:review) -%><br/>
<%= f.text_field :review_cont, :size => 25 ,:value => ""%>
</div>
</div>
<div class="two columns omega">
</div>
<div class="clear"></div>
<div class="form-buttons actions filter-actions" data-hook="admin_reviews_index_search_buttons">
<%= button Spree.t(:search), 'icon-search' %>
</div>
<%- end -%>
Getting undefined when i use the above mentioned variables. Please help me to solve this.
Upvotes: 0
Views: 372
Reputation: 211
Issue has been solved!
Defined the ransackable_attributes method in associated model Review.rb
for custom searchable attributes of that model.
def self.ransackable_attributes(auth_object = nil)
['title','review','user']
end
Upvotes: 1
Reputation: 3175
@cliffs - To be able to search by using ransack gem, you will first have to whitelist all those fields on which you wanna perform the search. So in your review.rb
model add the following line if you are inheriting it from Spree::Base
-
self.whitelisted_ransackable_attributes = %w[title, review]
else if you are inheriting it from ActiveRecord::Base
you have to define ransackable_attributes
as a class method
def self.ransackable_attributes(auth_object = nil)
['title','review','user']
end
and now try to search using ransack
.
Hope this helps you.
Upvotes: 1