Cliff_Cleet
Cliff_Cleet

Reputation: 211

Undefined method for <variable>_cont in spree - Ruby on Rails

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 methodreview _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

Answers (2)

Cliff_Cleet
Cliff_Cleet

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

Nimish Gupta
Nimish Gupta

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

Related Questions