I am using https://github.com/taxweb/ransack_advanced_search to search a table using condition groups. However, I can't seem to get this to work (yes, I am new to this!).
The set-up seems simple enough, and I followed the instructions to the letter, but the search simply results in all records being displayed (if indeed it occurs at all). Any help appreciated.
Controller:
class QuizzesController < ApplicationController
before_action :set_quiz, only: [:show, :edit, :update, :destroy]
def index
#search = Quiz.search(params[:q])
#results = #search.result().includes(:category, :genre)
if params[:tag]
#quizzes = Quiz.tagged_with(params[:tag])
else
#quizzes = Quiz.all
end
end
def new
#quiz = Quiz.new
end
def create
#quiz = Quiz.new(quiz_params)
if #quiz.save
redirect_to quizzes_path
else
render "new"
end
end
def edit
#quiz = Quiz.find(params[:id])
end
def update
if #quiz.update_attributes(quiz_params)
redirect_to quizzes_path
else
render "edit"
end
end
def show
#quiz = Quiz.find(params[:id])
end
def destroy
#quiz.destroy
respond_to do |format|
format.html { redirect_to quizzes_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_quiz
#quiz = Quiz.find(params[:id])
end
def quiz_params
params.require(:quiz).permit(:genre, :title, :image, :tags, :Actions, :q, :tag_list, :name, :category, :category_id, :genre_id, :tag_me, :sample_text, :name)
end
end
Model:
class Quiz < ActiveRecord::Base
def self.ransackable_associations(*)
%w( category genre )
end
def self.ransackable_attributes(*)
%w( category title genre tag_me ) + _ransackers.keys
end
mount_uploader :image, ImageUploader
belongs_to :category
belongs_to :genre
acts_as_taggable
validates :title, :presence => {:message => "Can't be blank." }
validates :image, :presence => {:message => "Can't be blank." }
validates :tag_me, :presence => {:message => "Can't be blank." }
validates :sample_text, :presence => {:message => "Can't be blank." }
validates :tag_list, :presence => {:message => "Can't be blank." }
validates :category_id, :presence => {:message => "Can't be blank." }
validates :genre_id, :presence => {:message => "Can't be blank." }
end
Routes:
Rails.application.routes.draw do
root "quizzes#index"
get 'tags/:tag', to: 'quizzes#index', as: :tag
resources :quizzes do
collection do
match :advanced_search, to: 'quizzes#index', via: :post
end
end
end
application.html.erb (head):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>QuizTags</title>
<!-- Bootstrap Core CSS -->
<!-- <link href="css/bootstrap.min.css" rel="stylesheet"> -->
<%= tinymce_assets %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
<%= yield(:ransack_advanced_search_setup) %>
etc.
index.html.erb:
<%= render partial: 'ransack_advanced_search/advanced_search',
locals: {
search_url: advanced_search_quizzes_path,
redirect_path: quizzes_path
}
%>
<table id="quizzes" class="table table-striped table-bordered table-responsive">
<thead>
<tr>
<th>Category</th>
<th>Genre</th>
<th>Title</th>
<th>Image</th>
<th>Tags</th>
<th>Actions</th>
</tr>
</thead>
<% #quizzes.each do |quiz| %>
<tr>
<td><%= quiz.category.name %></td>
<td><%= quiz.genre.name %></td>
<td><%= quiz.title %></td>
<td><%= image_tag quiz.image_url(:thumb).to_s %></td>
<td><%= quiz.tag_me %></td>
<td><%= link_to "View", quiz %> <br> <%= link_to 'Edit', edit_quiz_path(quiz)
%> <br> <%= link_to 'Delete', quiz, method: :delete, data: { confirm: 'Are you sure?' } %> </td>
</tr>
<% end %>
</table>
Many thanks - any help appreciated.
Change #results in your controller and change it to #quizzes and get rid of the if statement for now just to see if you can get it working correctly.
Related
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>List Page</title>
</head>
<body>
<h1>List Page</h1>
INSERT DATA
<hr/>
<table width = "100%" border="1">
<tr>
<td>DELETE</td>
<td>EDIT</td>
<td>ID</td>
<td>Name</td>
<td>Model Number</td>
<td>Series</td>
</tr>
<%= data.forEach((item, index) => { %>
<tr>
<td>DELETE</td>
<td>EDIT</td>
<td><%= item.id %></td>
<td><%= item.name %></td>
<td><%= item.modelnumber %></td>
<td><%= item.series %></td>
</tr>
<%= }) %>
</table>
</body>
</html>
I'm currently having a small problem with syntaxError. I checked as
far as i can but i failed. Can you tell me is there some miss typo in
there?
I wanna show this to website but it doesn't give me a hint.. I really
have no clue of where is wrong.. Please help me..
Welcome to SO, You need to put data.foreach() without this ejs tag <%= but this ejs tag <%. So your code should look like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>List Page</title>
</head>
<body>
<h1>List Page</h1>
INSERT DATA
<hr/>
<table width = "100%" border="1">
<tr>
<td>DELETE</td>
<td>EDIT</td>
<td>ID</td>
<td>Name</td>
<td>Model Number</td>
<td>Series</td>
</tr>
<!-- Here is the first change -->
<% data.forEach((item, index) => { %>
<tr>
<td>DELETE</td>
<td>EDIT</td>
<td><%= item.id %></td>
<td><%= item.name %></td>
<td><%= item.modelnumber %></td>
<td><%= item.series %></td>
</tr>
<!-- Here is the second change -->
<% }) %>
</table>
</body>
</html>
You should use <%%> to contain logic code , such as :
<% data.forEach((item, index) => { %>
<tr>
<td>DELETE</td>
<td>EDIT</td>
<td><%=item.id%></td>
<td><%=item.name%></td>
<td><%=item.modelnumber%></td>
<td><%=item.series%></td>
</tr>
<% }) %>
I am creating shopping cart system by using vueJs. I want to display the list of item that user want to by but when I run the application and try to add product in checkout list ,I am getting following errors in google chrome console windows when I want to add the item into list.
[Vue warn]: Error in render: "TypeError: Cannot read property 'name' of undefined"
(found in <Root>)
warn # vue.js:634
vue.js:1897 TypeError: Cannot read property 'name' of undefined
at eval (eval at createFunction (vue.js:11628), <anonymous>:3:265)
at Proxy.renderList (vue.js:2658)
at Proxy.eval (eval at createFunction (vue.js:11628), <anonymous>:3:183)
at Vue._render (vue.js:3545)
at Vue.updateComponent (vue.js:4061)
at Watcher.get (vue.js:4472)
at Watcher.run (vue.js:4547)
at flushSchedulerQueue (vue.js:4305)
at Array.<anonymous> (vue.js:1989)
at flushCallbacks (vue.js:1915)
logError # vue.js:1897
cart.html:91 Uncaught (in promise) TypeError: Cannot read property 'price' of undefined
at cart.html:91
Here is my cart.html code .
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="bootstap.css">
<!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>-->
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>-->
<!--<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.js">
</script>
</head>
<body>
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="index.html">Shop</a>
</li>
<li class="nav-item">
<a class="nav-link" href="index.html">Show All Products</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/AddProducts.html">Add Product</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.html"> cart</a>
</li>
</ul>
</nav>
<br />
<div class="container" id="app">
<h2>Your cart</h2>
<table class="table table-striped">
<thead>
<tr>
<th>Product</th>
<th>quantity</th>
<th>Rate</th>
<th>vendor</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr v-for="cartItem in cartItems">
<td>{{cartItem.product.name}}</td>
<td>
<button type="button" class="btn btn-primary" v-on:click="changequantity(cartItem.productId,-1)">-</button>
{{cartItem.quantity}}
<button type="button" class="btn btn-primary" v-on:click="changequantity(cartItem.productId,+1)">+</button>
</td>
<td>{{cartItem.product.price}}</td>
<td>{{cartItem.product.vendor.name}}</td>
<td>{{cartItem.quantity*cartItem.product.price}}</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td><b>Total</b></td>
<td>{{this.totalPrice}}</td>
</tr>
</tbody>
</table>
</div>
<script>let app = new Vue({
el: "#app",
data: {
totalPrice: 0,
price: 0,
cartItems:[]
},
methods:{
fetAllcartItems(){
new Promise((resolve)=>{
axios.get('/api/cart').then(function (response) {
resolve(response.data)
})
}).then((data)=>{
console.log(data)
this.cartItems=data
// console.log(data)
for(d in data){
this.totalPrice = this.totalPrice+ (d.quantity )* (d.product.price);
}
// console.log(this.products)
})
},
changequantity(id,quantity){
var obj = {id : id , quantity: quantity}
// let iddd = parseInt(id)
console.log(this.cartItems)
let index =this.cartItems.findIndex(item => item.productId == id)
this.totalPrice = this.totalPrice + this.cartItems[index].product.price * quantity
if(this.cartItems[index].quantity ===1 && quantity===-1){
this.cartItems.splice(index ,1);
}
new Promise((resolve)=>{
axios.post('/api/cart/add',obj).then(function (response) {
resolve(response.data)
})
}).then((data)=>{
console.log(data)
if(data.quantity>0)
this.cartItems[index].quantity = data.quantity
/*for(d of data){
this.totalPrice = this.totalPrice+ (d.quantity )* (d.product.price);
}*/
})
// location.reload();
}
}
})
app.fetAllcartItems();</script>
</body>
</html>
Here is the screen shot when I clicked the buy button.
Here is the screen shot when I run the applications..
To see why name is showing you need to check which data you are getting, check it on VueDevtool or else make put console.log(this.cartItems) on a proper place and see how its related , make sure that in this object cartItems is an array of object where poduct is also object and name has value/null.
Also for(d in data) , replace with for(let d in data)
for(d in data){ seems almost certainly wrong. Perhaps you meant for(const d of data) {? In its original form d is a string key, not the item in the array. That's plausibly the cause of the second error, the one about price.
For the error about name I would guess it's this:
<td>{{cartItem.product.vendor.name}}</td>
It looks like cartItem.product.vendor is undefined in some cases.
I strongly suggest you start using a linter. Your code is full of other small defects that I would expect a linter to pick up for you.
For starters, you shouldn't be creating all those new promises.
After initialize ejs variable, i cant change value and increment operator not working.
Here is my code:
<% results1.forEach(function(result1, index){ %>
<% results2.forEach(function(result2, index1){ %>
<% if(result1.id==result2.parent)
{
var i=1; %>
<tr>
<td><%= index+1 %>.<%= i %></td>
<td><%= result2.title %></td>
<td><%= result1.title %></td>
<td align="center"><%= result2.views %></td>
</tr>
<% i++;
} %>
<% }); %>
<% }); %>
In the above code I declared a variable i and bottom I added i++.
i should be declared outside forEach statement, otherwise is redeclared at every cicle
correct the code as above
<% results1.forEach(function(result1, index){ %>
<% var i=1; results2.forEach(function(result2, index1){ %>
<% if(result1.id==result2.parent)
{
<tr>
<td><%= index+1 %>.<%= i %></td>
<td><%= result2.title %></td>
<td><%= result1.title %></td>
<td align="center"><%= result2.views %></td>
</tr>
<% i++;
} %>
<% }); %>
<% }); %>
Since yesterday I have been trying to install authlogic in a project. As I can see, all the examples and the documentation are oriented to older versions of both rails and authlogic. However, I tried to follow :
the example in the documentation
the railscast
other websites examples like: http://www.logansbailey.com/2010/10/06/how-to-setup-authlogic-in-rails-3/ (for me, the most useful tutorial until now)
I don't get authlogic working properly.
I installed the gem trough the gemfile and the bundle install order.
I generated a model user and ran the migration
$ rails generate scaffold user username:string email:string crypted_password:string password_salt:string persistence_token:string
$ rake db:migrate
I add the following line to the model user.rb:
acts_as_authentic
then, I put a link to register a new user: link_to "Register", new_user_path
I edit /app/views/users/index.html.erb to look like:
<h1>Listing users</h1>
<table>
<tr>
<th>Username</th>
<th>Email</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #users.each do |user| %>
<tr>
<td><%= user.username %></td>
<td><%= user.email %></td>
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New User', new_user_path %>
and app/views/users/_form.html.erb to look like:
<%= form_for(#user) do |f| %>
<% if #user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :username %><br />
<%= f.text_field :username %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Now, when I try to register an user, I get two errors:
-Password is too short (minimum is 4 characters)
-Password confirmation is too short (minimum is 4 characters)
I have put longer passwords but it doesn't work.
Any help?
Thank you
Just based on the error messages without seeing the users controller, it appears that password and password_confirmation are not being passed to the user model. This may be a Rails 4 preventing mass assignment issue. To allow this, in the create method in the users controller, you can say:
#user = User.new(user_params)
and then define the user_params method:
def user_params
params.require(:user).permit(:password, :password_confirmation, :name, :email)
end
Using paperclip and ruby-mp3info to upload and read file info, I have a form that creates a playlist and its children, tracks:
<%= form_for(#playlist) do |f| %>
<% if #playlist.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#playlist.errors.count, "error") %> prohibited this playlist from being saved:</h2>
<ul>
<% #playlist.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label "Name: " %>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label " Image: " %>
<%= f.file_field :photo %>
</div>
<br>
<div class="field">
<br>
<%= f.text_area :description, :size => "80x3"%>
</div>
<br>
<div class="field">
<%= f.fields_for :tracks, Track.new do |ff| %>
<%= ff.file_field :audio %>
<% end %>
</div>
<% if !#playlist.tracks.blank? %>
<table id="tracks" class="table">
<thead>
<tr>
<th>Track</th>
<th>Album</th>
<th>Artist</th>
<th>Label</th>
</tr>
</thead>
<tbody>
<%= f.fields_for :tracks do |ff| %>
<%= render "track_fields", :f => ff %>
<% end %>
</tbody>
</table>
<% end %>
<div class="actions">
<%= f.submit "Save" %>
</div>
<% end %>
The problem with uploading a file is that I won't have it until I click on the Save button. So I read the info from within my controller. Within the update method of my Playlist controller, I try to create a new track by the following code:
def update
track = #playlist.tracks.new()
Mp3Info.open(playlist_params["tracks_attributes"]["0"]["audio"].path.to_s) do |info|
track.audio_file_name = info.tag.title
track.artist = info.tag.artist
track.album = info.tag.album
# tracknum = info.tag.tracknum.to_s
end
respond_to do |format|
if #playlist.update(playlist_params)
format.html { redirect_to #playlist, notice: 'Playlist was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #playlist.errors, status: :unprocessable_entity }
end
end
end
The problem is that the code in my update method will create TWO instances of tracks when I only want one. How do I create only the instance that I am creating from within my controller and ignore the new track that is being created from within the form?
Are there alternative ways to do this?
You are getting two records in tracks table because one you are creating from form (with track_attributes) and other you are creating in update action.
If you just need to update few properties of the track to be saved then do it on the track coming in params[:playlist][:tracks_attributes].
Change the update action as below:
def update
Mp3Info.open(playlist_params["tracks_attributes"]["0"]["audio"].path.to_s) do |info|
params[:playlist][:tracks_attributes]["0"][:audio_file_name] = info.tag.title
params[:playlist][:tracks_attributes]["0"][:artist] = info.tag.artist
params[:playlist][:tracks_attributes]["0"][:album] = info.tag.album
# tracknum = info.tag.tracknum.to_s
end
respond_to do |format|
if #playlist.update(playlist_params)
format.html { redirect_to #playlist, notice: 'Playlist was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #playlist.errors, status: :unprocessable_entity }
end
end
end
This will create only one associated Track record for a Playlist in tracks table.