I am using pg_search and have some trouble with localization.
I have shop_item model that have title1, title2, description1, description2 attributes. Depends from language I am using combination of title1 + description1, or title2 + description2
In application controller i have a method that set locale:
class ApplicationController < ActionController::Base
before_action :set_locale
private
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
end
ShopItemsController:
def index
if params[:search].present?
#shop_items = ShopItem.search_for_items(params[:search]).paginate(:page => params[:page], :per_page => 32).order('created_at DESC')
else
#shop_items = ShopItem.all.paginate(:page => params[:page], :per_page => 32).order('created_at DESC')
end
end
And in my shop_items/index.html.erb I have:
<%= form_tag shop_items_path, :method => 'get' do %>
<%= text_field_tag :search, params[:search], autofocus: true, type: "text", placeholder: 'search for messages'%>
<%= submit_tag "search", type: "submit"%>
<% end %>
</br>
<% if current_page?(locale: :ua)%>
<div class="row">
<% #shop_items.each do |si| %>
<div class="col m3 ">
<div class="card hoverable">
<div class="card-image">
<%= image_tag si.shop_image.url(:large) %>
</div>
<div class="card-content"-->
<span class="card-title truncate"><td><%= si.title1 %></td></span>
<p><%= t(:price)%>: <%= si.price%></p>
</div>
<div class="card-action">
<%= link_to t(:details), shop_item_path(si) %>
<%= link_to t(:edit), edit_shop_item_path(si) if current_user.present? and current_user.admin? %>
<%= link_to t(:destroy), si, method: :delete, data: { confirm: 'Are you sure?' } if current_user.present? and current_user.admin? %>
</div>
</div>
</div>
<% end %>
</div>
<% end %>
If I am going to shop_items_path I see in my browser next url as default:
http://localhost:3000/shop_items?locale=ua
I can see all my shop_items, but if I am removing locale from url, like:
http://localhost:3000/shop_items
All items are disappear
When I am using search I have url like:
http://localhost:3000/shop_items?utf8=%E2%9C%93&search=item&commit=search
As you can see locale is missing, as the result I can see any shop_items after search.
My question is how to store current locale and include it in search query?
Thanks for any solution!
UPDATED:
Rails.application.routes.draw do
root :to => 'shop_items#index'
resources :shopping_contacts
resources :cart_items
resources :shopping_carts do
#resources :contact_infos
resources :shopping_contacts
resources :cart_items
resources :cart_confirms
end
resources :shop_items do
resources :cart_items
end
resources :contact_us
resources :contacts, only: [:new, :create, :edit, :update, :index, :destroy]
get 'password_resets/new'
get 'password_resets/edit'
get 'sessions/new'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
get '/signup', to: 'users#new'
post '/signup', to: 'users#create'
resources :users
resources :main_shots
end
Ok thinks for update, maybe you should follow these steps.
1st nest yours routes in 'scope '(:locale)', locale: /en|es/ do:' like that.
Rails.application.routes.draw do
scope '(:locale)', locale: /en|es/ do
root :to => 'shop_items#index'
resources :shopping_contacts
resources :cart_items
resources :shopping_carts do
#resources :contact_infos
resources :shopping_contacts
resources :cart_items
resources :cart_confirms
end
resources :shop_items do
resources :cart_items
end
resources :contact_us
resources :contacts, only: [:new, :create, :edit, :update, :index, :destroy]
get 'password_resets/new'
get 'password_resets/edit'
get 'sessions/new'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
get '/signup', to: 'users#new'
post '/signup', to: 'users#create'
resources :users
resources :main_shots
end
end
2nd step add this method like that in application_controller.rb:
before_action :set_locale
def set_locale
I18n.locale = params.fetch(:locale, I18n.default_locale).to_sym
end
def default_url_options
{ locale: I18n.locale == I18n.default_locale ? nil : I18n.locale }
end
Last step have you set defautl local in application.rb ?:
config.i18n.default_locale = :en
Give me your feedback, good luck.
Related
This code is all based on the Ruby on Rails tutorial by Michael Hartl. I created an assigned action in my users_controller with
def assign
puts "in assign..."
#scout = User.find(params[:follower_id])
#der = User.find(params[:followed_id])
end
I realize this doesn't do anything currently, but in the _follow partial, I have
<%= form_for #user, url: { action: "assign" } do |f| %>
<div><%= hidden_field_tag :follower_id, #user.id %></div>
<%= f.label :followed_id, "Assign #{#user.name} to" %>
<%= f.collection_select :following, #ders, :id, :name, prompt: true %>
<%= f.submit "Assign", class: "btn btn-primary" %>
<% end %>
But I'm getting the error No route matches {:action=>"assign", :controller=>"users", :id=>"4"}. I'm new to rails so this could just be a stupid question. What am I doing wrong? Do I need to modify my routes.rb file? Also, if I tried <%= form_for #user do |f| %>, how does the controller know which action to use? Is it based on the action displaying the form?
Edit: my routes.rb file is
Rails.application.routes.draw do
root 'static_pages#home'
get 'help' => 'static_pages#help'
get 'about' => 'static_pages#about'
get 'contact' => 'static_pages#contact'
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
resources :users do
member do
get :following, :followers
end
end
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :relationships, only: [:create, :destroy]
end
Edit 2: the HTML generated by #Rich's form_for block is
<form class="edit_user" id="edit_user_5" action="/users/5/assign" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓">
<input type="hidden" name="_method" value="patch">
<input type="hidden" name="authenticity_token" value="...">
<label for="user_followed_id">Assign Mr. Marley Muller to</label>
<select name="user[following]" id="user_following">
<option value="1">Example User</option>
<option value="2">Matthew Swartz</option>
<option value="3">Joseph Swartz</option>
</select>
<input type="submit" name="commit" value="Assign" class="btn btn-primary">
</form>
Which makes sense why I'm currently getting a can't find id error since it's not sending a real id (edit_user_5)
Edit 3: Here are the parameters being passed for the request
Started PATCH "/users/6/assign" for 68.100.59.128 at 2015-12-15 03:54:39 +0000
Processing by UsersController#assign as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"...", "user"=>{"following"=>"2"}, "commit"=>"Assign", "id"=>"6"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 6]]
Unpermitted parameter: following
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", nil]]
Completed 404 Not Found in 9ms (ActiveRecord: 1.0ms)
ActiveRecord::RecordNotFound (Couldn't find User with 'id'=):
app/controllers/users_controller.rb:69:in `assign'
Edit 4: With the following routes file,
Rails.application.routes.draw do
root 'static_pages#home'
get 'help' => 'static_pages#help'
get 'about' => 'static_pages#about'
get 'contact' => 'static_pages#contact'
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
resources :users do
member do
get :following, :followers
match :assign, to: :assign, via: [:post, :patch]
end
end
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :relationships, only: [:create, :destroy]
end
and the following form for assigning one user to follow another,
<%= form_for #user, url: { action: "assign" } do |f| %>
<%= f.label :follower_id, "Assign #{#user.name} to" %>
<%= f.collection_select :following, #ders, :id, :name, prompt: true %>
<%= f.submit "Assign", class: "btn btn-primary" %>
<% end %>
I am getting the ActiveRecord::RecordNotFound in UsersController#assign error of Couldn't find User with 'id'=, but with the following parameters:
{"utf8"=>"✓",
"_method"=>"patch",
"authenticity_token"=>"...",
"user"=>{"following"=>"3"},
"commit"=>"Assign",
"id"=>"4"}
The ID's are correct: "user"=>{"following"=>"3"} and "id"=>"4", I believe I am just trying to access them incorrectly. This is the assigns action in the users controller:
def assign
#scout = User.find(params[:id])
#der = User.find(params_hash[:followed_id])
# make scout follow der here
redirect_to #scout
end
Thoughts?
In your routes.rb file you have to define the route for the specific controller action like that:
resource :users do
member do
post 'assign' # change the request method to 'put'
end
end
It will then generate a route for your assign method in the controller like: users/4/assign
For more info visit guides
To add to Emu's answer, the code you have won't work...
def assign
puts "in assign..."
#scout = User.find(params[:follower_id])
#der = User.find(params[:followed_id])
end
The params you'd get from the form_for object would be structured as:
params[:user][:follower_id]
params[:user][:followed_id]
You'd have to use the following:
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def assign
#scout = User.find params[:id]
#der = User.find params_hash[:followed_id]
end
private
def params_hash
params.require(:user).permit(:followed_id)
end
end
You could also get rid of the hidden field in your form if you're using the same #user object to populate it:
<%= form_for #user, url: { action: "assign" } do |f| %>
<%= f.label :followed_id, "Assign #{#user.name} to" %>
<%= f.collection_select :following, #ders, :id, :name, prompt: true %>
<%= f.submit "Assign", class: "btn btn-primary" %>
<% end %>
Update
You need to include :assign in your routes:
Rails.application.routes.draw do
root 'static_pages#home'
resources :static_pages, only: [], path: "" do
collection do
get :help, :about, :contact
end
end
resources :sessions, only: [:new, :create, :destroy], path_names: {new: "login", create: "login", destroy: "logout"}
resources :users, path_names: { new: "signup" } do
member do
get :following, :followers, :assign
end
end
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :relationships, only: [:create, :destroy]
end
It turns out it was a combination of Emu and Rich's answers. The form in the HTML is
<%= form_for #user, url: { action: "assign" } do |f| %>
<%= f.label :follower_id, "Assign #{#user.name} to" %>
<%= f.collection_select :following, #ders, :id, :name, prompt: true %>
<%= f.submit "Assign", class: "btn btn-primary" %>
<% end %>
With controller action
def assign
#scout = User.find(params[:id])
#der = User.find(params[:user][:following])
#scout.follow(#der)
redirect_to #scout
end
and routes as
Rails.application.routes.draw do
root 'static_pages#home'
get 'help' => 'static_pages#help'
get 'about' => 'static_pages#about'
get 'contact' => 'static_pages#contact'
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
resources :users do
member do
get :following, :followers
match :assign, to: :assign, via: [:post, :patch]
end
end
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :relationships, only: [:create, :destroy]
end
I am trying to come up with upvote/downvote method in my app and I running into a no method error.
Here is my voter form:
<div>
<div class= 'pull-left'>
<div><%= link_to " ", post_up_vote_path(post), class: 'glyphicon plyphicon-chevron-up', method: :post %></div>
<div><strong><%= post.points %></strong></div>
<div><%= link_to " ", post_down_vote_path(post), class: 'glyphicon plyphicon-chevron-up', method: :post %></div>
</div>
Here are my routes:
App::Application.routes.draw do
devise_for :users
resources :users
resources :topics do
resources :posts, except: [:index] do
resources :comments, only: [:create, :destroy]
post '/up-vote' => 'votes#post_up_vote', as: :up_vote
post '/down-vote' => 'votes#post_down_vote', as: :down_vote
end
end
get 'about' => 'welcome#about'
root to: 'welcome#index'
end
And here is my partial call:
<%= render partial: 'votes/voter', locals: { post: post } %>
Now I don't think there is anything wrong with my partial call or my voter partial because everything works until I try to route it.
First, you will need to change up your routes a bit.
resources :posts, except: [:index] do
resources :comments, only: [:create, :destroy]
post 'upvote', on: :member
post 'downvote', on: :member
end
The reason these are member routes instead of collection routes is being they apply to a specific member of the collection of posts...a single Post.
Then, you will want to run the command, rake routes in your Terminal to see what the appropriate path methods are. It should be something like
upvote_post_path(:id)
which requires an object be passed in..so in your view you would use it like you currently are.
upvote_post_path(post)
My error says that:
Couldn't find Question with 'id'=your_questions"
and
ActiveRecord::RecordNotFound in QuestionsController#show
What should I do to fix it?
def show
#question = Question.find(params[:id])
#answer = Answer.new
end
on the second line it says where the error is.
Edit:
The Index View File
<%= form_for(#question) do |f| %>
<%= render 'common/form_errors', object: #question %>
<p>
<%= f.label :body, "Question" %><br />
<%= f.text_field :body %>
<%= f.submit "Ask a Question" %>
</p>
<% end %>
Rails.application.routes.draw do
get "/" => "main_app#index"
get "/location" => "location#location"
post "/location/index" => "location#index"
get "/location/index" => "location#index"
get "/location/directions" => "location#directions"
root to: 'questions#index'
get '/logout', to: 'sessions#destroy', via: :delete
resources :users, only: [:new, :create]
resources :sessions, only: [:new, :create]
resources :questions, except: [:new] do
resources :answers, only: [:create]
end
get '/register', to: 'users#new'
get '/login', to: 'sessions#new'
get '/logout', to: 'sessions#destroy', via: :delete
get '/questions/:id', to: 'questions#your_questions'
get '/search', to: 'questions#search'
You mention you have this route:
get '/questions/your_questions', to: 'questions#your_questions
If you also have a route like following the restful style, you should also have something like:
get 'questions/:id', to: 'questions#your_questions'
Or a resource call. Anyway, so Rails is actually trying to access your show action passing "your_questions" as the id for the route. Write this route like this:
get '/questions/:id', to: 'questions#show
This means: "If a request using the GET HTTP method follows the url 'questions/:id', then go to controller: questions and its action(method in the controller) called: your_questions" and pass into the params hash the value of id as in the URL.
I'm implementing a custom update function called update_status for my users controller. I need some help with the routing. what I want to do is update a status that only admins can access. I'm calling the update function via a form helper through the edit function in the users controller. This is my code for the form helper:
<%= form_for #user, :url => url_for(:controller => "users", :action => "update_status"), method: :put do |f| %>
<%= render "shared/error_messages", object: f.object %>
<%= f.check_box :admin %>
<%= f.label :admin %>
<%= f.check_box :editor %>
<%= f.label :editor %>
<%= f.submit "Save Changes", class: "btn btn-primary" %>
<% end %>
But when I click save changes all I get is this error
I want to route the action so that the user id can be resolved.
Controller action code:
def update_status
if #user.update_attributes(status_params)
flash[:success] = "User updated"
redirect_to #user
else
render 'edit'
end
end
Routes:
Transpub::Application.routes.draw do
resources :users do
member do
put 'update_status'
end
end
resources :papers
resources :comments
resources :reviews
resources :sessions, only: [:new, :create, :destroy]
resources :relationships, only: [:create, :destroy]
resources :comments, only: [:create, :destroy]
resources :subject_field, only: [:create, :destroy]
#get "users/new"
root "static_pages#home"
match "/signup", to: "users#new", via: "get"
match "/signin", to: "sessions#new", via: "get"
match "/signout", to: "sessions#destroy", via: "delete"
match "/help", to: "static_pages#help", via: "get"
match "/about", to: "static_pages#about", via: "get"
match "/contact", to: "static_pages#contact", via: "get"
match "/search_papers", to: "papers#index", via: "get"
match "/browse_papers", to: "papers#browse", via: "get"
In your routes files, look for the part that corresponds to the users controller and make sure that you have the following code
resources :users do
put :update_status, on: :member
end
That will declare the route. Another thing you have to update is the url of the form. Change the url to
form_for #user, :url => [:update_status, #user], html: { method: :put } do |f|
I'm following the http://ruby.railstutorial.org/
and I'm in chapter10 --build the microposts
but I named the_microposts not microposts
and then I had this problem:
When I visit static_page/home , it shows:
undefined method `the_microposts_path' for #<#:0xb628402c>
and the application trace is:
app/views/shared/_the_micropost_form.html.erb:1:in _app_views_shared__the_micropost_form_html_erb___1052260201__619399208'
app/views/static_pages/home.html.erb:9:in_app_views_static_pages_home_html_erb_733532872_628014758'
It seems that I didn't defined the method?
But I had defined it in my static_pages controller:
def home
#the_micropost = current_user.the_microposts.build if signed_in?
end
My home page:
<section>
<%= render 'shared/the_micropost_form' %>
</section>
and my _the_micropost_form.html.erb is:
<%= form_for(#the_micropost) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose new micropost..." %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
my user models:
has_many :the_microposts, dependent: :destroy
the_micropost models:
belongs_to :user
My routes:
resources :users
resources :sessions, only: [:new, :create, :destroy]
root 'static_pages#home'
match '/signup', to: 'users#new', via: 'get'
match '/signin', to: 'sessions#new', via: 'get'
match '/signout', to: 'sessions#destroy', via: 'delete'
match '/help', to: 'static_pages#help', via: 'get'
match '/about', to: 'static_pages#about', via: 'get'
match '/contact', to: 'static_pages#contact', via: 'get'
is anything wrong??
I always follow the steps, is it because I defined the different name?(the_microposts as microposts)
You need to define route for Micropost resource just like you have defined for users and sessions. Update your config/routes to include resource :microposts.
resources :users
resources :sessions, only: [:new, :create, :destroy]
resources :microposts
root 'static_pages#home'
...