route issue menu.29 instead of menu/29 - ruby-on-rails

first i listed all the menu that the guest added inside the package that he also added i listed them with this
_menuadded.html.erb
<h1>menu you added</h1>
<% #reservation_package.package_line_items.each do |menu|%>
<p><%= link_to menu.menu.name, menu_reservation_reservation_package_reservation_package_pages_path(#reservation,#reservation_package,menu) %></p>
<p><%= link_to "delete item" ,reservation_package_package_line_item_path(#reservation_package,menu), :method => :delete%></p>
<%end%>
then i try to route to the next static page with this <p><%= link_to menu.menu.name, menu_reservation_reservation_package_reservation_package_pages_path(#reservation,#reservation_package,menu) %></p>
and the it produce this URL http://localhost:3000/reservations/10/reservation_packages/39/reservation_package_pages/menu.29
im just wondering if how can i catch the menu that he opened i mean how to catch this localhost:3000/reservations/10/reservation_packages/39/reservation_package_pages/menu.29
in my menu semi static page controller where this route to,i tried this
#reservation_package = ReservationPackage.find(params[:reservation_package_id])
#menu = Menu.find(params[:id])
but didn't work at all im just wondering if im doing it right or if im wrong can you give me a advice how to implement this kind of module? thanks more power
ROUTES:
resources :services
resources :reservations do
resources :pages do
collection do
get :functionroomlist
get :packagelist
get :package
# get :menu
end
end
resources :reservation_packages do
resources :reservation_package_pages do
collection do
get :menulist
get :menu
end
end
resources :package_line_items
end
resources :reservation_function_rooms
end

We had an similar issue I hope i can help you a little bit
my user can create an productlist and he can directly add new products on it. On the show-form i set an link like this
<%= link_to 'Create', new_product_path(:procuctlist => #productlist.id) %>
In the controller of products i definded the new-Action so
def new
#product_entry = ProductEntry.new
#product_entry.productlist_id = params[:productlist]
respond_to do |format|
format.html # new.html.erb
format.json { render json: #wishlist_entry }
end
end
The Models are defined so
class Product < ActiveRecord::Base
belongs_to :productlists
has_many :registrations, :dependent => :destroy
validates :entry_name, :description, :presence => true
end
class Productlist < ActiveRecord::Base
has_many :products, :dependent => :destroy
end
the table products contains the field productlist_id.
The view of products in our first alpha version contains the productlist_id.
<div class="field">
<%= f.label :productlist_id %><br />
<%= f.number_field :productlist_id %>
</div>
We hope we could help you.

Related

Rails - Problem with passing local variables

I'm running Rails 6.0.3.2 and I want to render a partial passing a local variable to another controller view:
My routes:
Rails.application.routes.draw do
devise_for :users
root to: 'notebooks#index'
resources :notebooks, only: [:index, :new, :show, :create, :edit, :update, :destroy] do
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
collection do
get "list"
end
end
resources :tags
end
Notebook Model:
class Notebook < ApplicationRecord
has_one_attached :photo
validates :asin, presence: true, uniqueness: true
after_initialize :init
acts_as_list column: :position, add_new_at: :bottom
has_many :taggings
has_many :tags, through: :taggings
def init
self.edited ||= false
end
end
Tag Model
class Tag < ApplicationRecord
has_many :taggings
has_many :notebooks, through: :taggings
end
In Tag controller:
def index
#tags = Tag.all.order(created_at: :asc)
end
I tried to follow this guide and render the "index view" from Tags Controller on the "list view". The application finds the tags/_index.html file, but return the error undefined method `each' for nil:NilClass. Bellow my views code:
In app/views/notebooks/list.html.erb:
<%= render :partial => "tags/index" , locals: {tags: #tags}%>
In app/views/tags/_index.html.erb
<% tags.each do |tag| %>
<div>
<div class="d-flex">
<p><%= tag.id %></p>
<p><%= tag.name %></p>
</div>
<p>tag.taggings.count</p>
</div>
<% end %>
Anyone can point me what i'm doing wrong? I read the Layouts and Rendering in Rails documentation, but i don't have a clue why the instructions won't work on my project...
Thanks in advance!
The rails way to do this is just to create a partial for a single record:
# app/views/tags/_tag.html.erb
<div>
<div class="d-flex">
<p><%= tag.id %></p>
<p><%= tag.name %></p>
</div>
<p>tag.taggings.count</p>
</div>
You can then pass the collection to render and Rails will look up the partial and render it for each member in the collection:
<%= render #tags %>
This is short for:
<%= render partial: 'tag', collection: #tags %>
See Rendering Collections.

Routing a form for a polymorphic model's non polymorphic side

I have set up a polymorphic association between Event, Meeting, and TaskList such that:
An Event can have many TaskLists, A TaskList can belong to one Event.
A Meeting can have many TaskLists, A TaskList can belong to one Meeting.
This works and I can create task_lists from the view of these models. However my problem is that I want to be able to add TaskItem to each TaskList such that:
A TaskList can have many TaskItems, A TaskItem can belong to one TaskList.
I'm having trouble routing the form for the creation of a task item. I've created a "_form.html.erb" for this and am rendering it from the view of the task_item. I'm using the form below for this, at the moment from the events view, which shows the form fine but throws the routing error "No route matches [POST] "/events/3/task_lists/new.3" when clicked on submit.
_form.html.erb
<%= form_for TaskItem.new, url: new_polymorphic_path([#listable, #task_list, #task_item]) do |f| %>
<div class="field">
<%= f.label :content %><br />
<%= f.text_field :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I have also tried setting it up like below which doen't even show the form throwing the error "First argument in form cannot contain nil or be empty"
<%= form_for #task_item do %>
<div class="field">
<%= f.label :content %><br />
<%= f.text_field :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Models
class TaskList
belongs_to :listable, polymorphic: true
has_many :task_items
end
class TaskItem
belongs_to :task_list
end
class Event
has_many :task_lists, as: :listable
end
class Meeting
has_many :task_lists, as: :listable
end
Routes (added :show to task_lists, only: , as my link wouldnt work otherwise.)
concern :has_task_lists do
resources :task_lists, only: [:new, :index, :create, :show]
end
resources :events, :meetings, concerns: [:has_task_lists]
resources :task_lists, except: [:new, :index, :create] do
resources :task_items
end
task_items_controller (want it to redirect to the page item was created from, which is the show view for task_list)
def create
#task_item = #task_list.task_items.new(task_item_params)
if #task_item.save
redirect_to #task_list, notice: "Task Item Created"
else
render :new
end
end
task_lists_controller
before_action :load_listable
def show
#task_list = #listable.task_lists.find(params[:id])
end
def load_listable
klass = [Event, Meeting].detect { |c| params["#{c.name.underscore}_id"]}
#listable = klass.find(params["#{klass.name.underscore}_id"])
end
One of the key issues here is that task_items are nested a level too deep.
Rule of thumb: resources should never be nested more than 1 level
deep. A collection may need to be scoped by its parent, but a specific
member can always be accessed directly by an id, and shouldn’t need
scoping.
- Jamis Buck
So to untangle this we would declare the routes like so:
concern :has_task_lists do
resources :task_lists, only: [:new, :index, :create]
end
resources :events, :meetings, concerns: [:has_task_lists]
resources :task_lists, except: [:new, :index, :create] do
resources :task_items
end
The routing concern lets us re-use the nested routes.
Since we have gotten rid of the extra "parent" we can simplify the form:
form_for([ #task_list, #task_item || #task_list.task_items.new ])
#task_item || #task_list.task_items.new will prevent errors if you embed the form in another controller / action.
Added
You actually have to create the resource scoped to the parent. Just doing form_for([#a, #b]) does not automatically associate the records - it just generates the url and sets the form method (POST or PATCH).
class TaskItemsController < ApplicationController
before_action :set_task_list
def new
#task_item = #task_list.task_items.new
end
def create
#task_item = #task_list.task_items.new(task_item_params)
if #task_item.save
redirect_to task_list_path(#task_list), notice: "Task Item Created"
else
render :new
end
end
private
def set_task_list
#task_list = TaskList.find(params[:task_list_id])
end
# ...
end
When you call #task_list.task_items.new you are calling the .new method on the collection - so the new TaskItem will have the task_list_id column set.
Note that you can also write redirect_to #task_list and rails will figure the rest out. If you need to redirect to a nested resource such as the newly created item you would do:
redirect_to [#task_list, #task_item]

Simple learning app with Rails 4 - Course / Enrolment / User Not working

I am trying to build a simple learning app with rails 4.
here are my models:
class User < ActiveRecord::Base
has_many :enrollments
has_many :lectures, through: :enrollments
accepts_nested_attributes_for :enrollments
end
class Enrollment < ActiveRecord::Base
belongs_to :user
belongs_to :lecture
end
class Lecture < ActiveRecord::Base
has_many :enrollments
has_many :users, through: :enrollments
end
And here are my controllers
class EnrollmentsController < ApplicationController
before_action :authenticate_user!
def create
#enrollments = current_user.enrollments.build(enrollment_params)
if #enrollments.save
flash[:success] = "You have successfully enrolled."
redirect_to profile_path(current_user)
else
flash[:danger] = "Please try again."
redirect_to root_path
end
end
private
def enrollment_params
params.require(:enrollment).permit(:user_id, :lecture_id)
end
end
Here are my views:
lectures/index.html.erb
<% #lectures.each do |lecture| %>
<%= image_tag lecture.picture.url(:medium) %>
<p><%= truncate(lecture.description, length: 80) %> </p>
<%= link_to "Enroll Now", {:action=>"create", :controller=>"enrollments"}, :method => :post %>
<% end %>
The problem is that when you click on Enroll Now I have the following error:
ActionController::ParameterMissing in EnrollmentsController#create
param is missing or the value is empty: enrollment
def enrollment_params
params.require(:enrollment).permit(:user_id, :lecture_id)
end
How can i make it work? Need help please
In your lectures/index.html.erb file, you are not passing any data to the controller's action method.
<%= link_to "Enroll Now", {:action=>"create", :controller=>"enrollments"}, :method => :post %>
Might be better served with something a la
<%= link_to "Enroll Now", {:action=>"create", :controller=>"enrollments", :user_id => current_user.id**, :lecture_id => lecture.id}, :method => :post %>
# ** not sure how you snag the current user's id in your app but you'd need it.
Also, take a look at Routing in Rails. There are some super handy helper methods you can use that will allow you to do something like this (this was done quickly and may not be totally accurate but is offered to show you how you can use a route's path helper to clean up the code and make it even more readable):
<%= link_to 'Enroll Now', enrollments_path({enrollment: { user_id: current_user.id, lecture_id: lecture.id }}), :method => :post %>

Updating complex linked tables

How do I solve the following issue:
I want to add a new row to the table submitted_pictures, which is linked as follows:
game.rb
has_many :rounds
has_many :participants, :dependent => :destroy
has_many :submitted_pictures, :through => :rounds
has_many :users, :through => :participants
accepts_nested_attributes_for :participants
accepts_nested_attributes_for :rounds, :reject_if => :all_blank
round.rb
belongs_to :game
has_many :submitted_pictures, :dependent => :destroy
accepts_nested_attributes_for :submitted_pictures
submitted_picture.rb
has_one :round
has_one :game, :through => :rounds
belongs_to :user
So I could call:
<% #user.games.rounds.last.submitted_pictures.each do |blabla| %><% end>
I made a complex form using:
<%= form_for(#game) do |f| %>
<%= f.fields_for :round do |ff| %>
<%= ff.fields_for :submitted_pictures do |fff| %>
<%= fff.label :flickr_id %>
<%= fff.text_field :flickr_id %>
<% end %>
<% end %>
<%= f.submit "Submit Picture", class: "btn btn-primary" %>
<% end %>
Hoping to add a new submitted_picture with the flickr_id (which holds a httplink for now), linked to the the current game (#game).
I've been trying several things to update it but it doesnt seem to budge: (the update_attributes is totally wrong I see now :p)
def update
#game = Game.find(params[:id])
if #game.rounds.last.submitted_pictures.update_attributes(params[:id])
flash[:success] = "Pic Submitted!"
else
render :action => 'new'
end
end
Also
def update
#game = Game.find(params[:id])
if #game.save
flash[:success] = "Pic Submitted!"
redirect_to games_path
else
render :action => 'new'
end
end
I can't get it to work. I'm getting all kinds of errors, so instead of noting them all here I thought it would be best to ask for the best solution.
So in short, I'm wanting to add a submitted_picture to the latest round (most recent created_at) of the game.
I think nesting everything in a game form is making things unnecessarily complicated for you. If I understand correctly, you want to create a new submitted_picture and it needs to have a game selected. The round is not directly selected, but is just the latest for the game. (this sounds like a suspicious assumption--but it does keep things simpler so I'll roll with it)
So just make a new submitted_picture form, and add in a game select.
In your handler, pull the latest round from the game and merge that round into your params to save the new picture.
Does that do what you want?

rails create custom action

i created a small rails application for learning which has 3 models :
class Resource < ActiveRecord::Base
belongs_to :task
belongs_to :user
end
class User < ActiveRecord::Base
has_many :resources
has_many :tasks, :through=>:recources
end
class Task < ActiveRecord::Base
has_many :resources, :dependent => :destroy
has_many :comments, :dependent => :destroy
has_many :users, :through=>:resources
accepts_nested_attributes_for :resources,:comments
end
everything is ok - listing,creating etc. But i wanna make a view which user upload a text file that contains tasks (it is not important how i can read text file) so i read the file and fetch the tasks. I created a controller which name is upload :
class UploadController < ApplicationController
def index
end
def upload
flash[:notice]="Upload completed"
end
end
and index view like this :
<% if flash[:notice] %>
<p><%= flash[:notice] %></p>
<% end %>
<div class="upload">
<p>Select a project file</p>
<%= form_tag :controller=>:upload,:action => :upload,:method => :put do %>
<%= file_field 'Project File',:file %>
<%= submit_tag "Upload" %>
<% end %>
</div>
when i press upload button it gives me "Missing template upload/uploa...."
How can i accomplish this action, give me advice plz.
Thanks
Missing template upload/uploa...."
Rails is looking for a view: app/views/upload/upload.html.erb
PS. You'll need to add in :multipart => true in your form_for to upload a file ;)
Every action tries to render a template with the same name as itself if you don't specifically tell it what to render or redirect_to. So what you can do is this:
render :nothing => true
That should do what you want.
Also, the documentation is decent with regard to what you can do with render

Resources