I have two engines in refinerycms: product and order. Im trying to call "create" method of orders while being on the product show page, but cant get the right syntax.
The html is:
<%= form_tag({controller: 'orders', action: 'create'}, method: 'post') do %>
<%= submit_tag('Submit') %>
<% end %>
And the error is :
No route matches {:action=>"create", :controller=>"refinery/products/orders", :id=>"category1", :locale=>:en}
The route I`m looking for is(from rake routes log):
orders_orders POST /orders(.:format) refinery/orders/orders#create
I`ve tried different variants, like:
<%= form_tag(url_for({controller: 'orders', action: 'create'}), method: 'post') do %>
<%= submit_tag('Submit') %>
<% end %>
<%= form_tag({controller: 'refinery/orders/', action: 'create'}, method: 'post') do %>
<%= submit_tag('Submit') %>
<% end %>
And some other. But had no luck.
How can I call 'create' method of orders from products/show page and transfer there correct params?
Well, I have used a kind of workaround to accomplish my goal. Do not know if this is a ruby-way, but still:
1. I have created a new action in my products controller.
def ordering
#Call any method you like.
end
I have added this in routes:
post 'shop/products/ordering' => 'refinery/products/products#ordering'
Still this is not a good solution, because there is no way to call actually another controller`s method without directly creating an instance of this controller or marking the method as a class method, not instance.
In any case, I`d be very grateful if someone could explain in details or show any documentation on how to do such things directly.
UDP: I`ve found a good way in search engine for this cms.
<%= form_tag refinery.search_root_path, method: 'get' do %>
<%= label_tag 'query', t('.search_label') %>
<%= text_field_tag :query, {}, {type: "search", placeholder: t(".search_site_for"), value: (params[:query] if params[:query])} %>
<%= submit_tag t(".go") %>
<% end %>
Related
In my Rails 6 app, I have a Product and Order model.
On my products#show page, I have some fields and a button. What I need to do is send the info to the orders#new page so that this data is shown on the orders#new page.
I have tried to write some code based on Pass variables without model associations in Rails and how to pass parameters in params using form_tag method in rails, but my code seems completely wrong.
on products#show:
<%= form_tag(new_order_path do |form| %>
<%= form.input_field :comments %>
<%= form.button %>
<% end %>
With this code I get undefined method text_field' for nil:NilClass`.
I have tried adding attr_accessor :comments to both the Product and Order model, but it doesn't help.
I don't think that my approach or what I am trying to code is right. I was just trying to piece together parts from these answers.
Can someone please help me figure out the best way I can pass this data to Orders#new to show in that view?
<%= form_with url: "/search", method: :get do |form| %>
<%= form.label :query, "Search for:" %>
<%= form.text_field :query %>
<%= form.submit "Search" %>
<% end %>
from the docs
https://guides.rubyonrails.org/form_helpers.html
and the show path also requires an id
I feel like there's no easy way to do this in rails, but since I'm fairly noob in rails I decided to ask for solutions:
I have a form in a view that contains a single (text) input. How can I specify the form url such that it will do a GET to /something/<input> ?
I know I could:
use custom javascript code
post to an endpoint that would do the redirect
Is there any cleaner way?
(using rails 5.2.1 if relevant)
I think you could use something like this:
<%= form_tag(route_path method: :get) do %>
search <%= text_field_tag :search %>
<%= submit_tag 'Search' %>
<% end %>
It depends on which form helpers you use.
Maybe you can try this
In your form:
<%= form_with(url: "path_name/input_field_name", method: :get, local: true) do |f| %>
<%= f.text_field :input_field_name %>
<%= f.submit 'Search', input_field_name: nil %>
<% end %>
In your controller:
unless params[:input_field_name].blank?
#results = ModelName.where('input_field_name iLIKE ?', "%#{params[:input_field_name]}%")
end
So my form partial is loaded in my div id="secondary", which is hidden on first page load.
When the user hits a button with a class called toggleSidebar, then the _form.html.erb is shown.
I have overridden the partial to display a new form (even if update is pressed) when a user is not logged in like this:
<%= simple_form_for(Post.new, html: {class: 'form-horizontal' }) do |f| %>
As opposed to the regular version that looks like this, and is included in an if statement on this same partial:
<% if current_user and current_user.has_any_role? :editor, :admin %>
<%= simple_form_for(#post, html: {class: 'form-horizontal' }) do |f| %>
The real issue is in my view, when someone goes to Update, this is what happens when the user is logged out:
<%= link_to "Update", "#", class: "togglesidebar" %>
This is perfect, it executes the CSS and shows the empty form partial perfectly.
However, when a user is logged in, I want it to send the parameter parent_id: #post with the execution of the sidebar being toggled.
This is how it looks with a normal new_post_path view (i.e. the non-sidebar new post view):
<% if current_user %>
<%= link_to "Update", new_post_path(parent_id: #post) %>
<% end %>
This is what my PostController#New looks like:
def new
#post = Post.new(parent_id: params[:parent_id])
end
How do I either pass the params in the regular non new_post_path version, or tackle this another way?
You could probably use a helper method.
Just browse to the 'helper' directory under 'app' folder and create a file similar to [name]_helper.rb
In this file create a module by [name]Helper and declare your helper method in this module.
This module is automatically required by rails.
A small example might help you.
The code in the link_helper.rb under app/helper directory
module LinkHelper
def populate_link(link1, link2, parameter)
if current_user
public_send(link2, parameter)
else
link1
end
end
end
The code in views is
<%= link_to 'update', populate_link('#', 'new_requirement_path',parameter: 33) %>
I'm a bit confused by the question, but I think you may be just need to use a hidden field to pass the parent_id param back?
e.g./
<%= simple_form_for(Post.new, html: {class: 'form-horizontal' }) do |f| %>
<%= f.hidden_field :parent_id, { value: #post.try(:id) } %>
<% end %>
HTH?
I am also a bit confused, but the following railscast might help you. It shows how to embed data in an html-tag. You can probably do it the same way.
railscast-> passing data to javascript
Out of the possibilities there I'd recommend the data-attribute:
<%= simple_form_for,(Post.new, html: {class: 'form-horizontal' }, **data: {post_id: #post.id}**) do |f| %>
<% end %>
Im new to rails, and I am not able to understand how I can get data from a submitted form.
This is my form registerduser.html.erb
<%= form_tag("/submitform", :method => "get") do %>
<%= label_tag(:q1, "id:") %>
<%= text_field_tag(:q1) %>
<%= submit_tag("Submit") %>
<% end %>
How do I get the submitted values in this customers controller action?
def submitform
#customers_values = params[:q1]
end
routes.rb
get "customers/submitform"
error:
No route matches [GET] "/submitform"
You set wrong form url. It should be:
<%= form_tag('/customers/submitform', method: :get) do %>
...
or:
<%= form_tag(controller: :customers, action: :submitform, method: :get) do %>
...
One of the things I'm doing includes several links on the show view. For instance, I have a link (or button) for "Accepting", and another one for "Rejecting". Click on Accept, and the model updates the is_accepted field as true, click on Reject, and the is_accepted field is false.
Now, how best do I handle this? In ASP.NET, I would have simply created a LinkButton and written a handler, but Rails doesn't work that way, so I'm trying to figure out how to essentially replicate what a LinkButton would do.
Right now, I'm coding two forms on the same view, nearly identical, that look like this:
<%= form_for #thing do |f| %>
<%= hidden_field_tag 'thing[is_accepted]', '1' %>
<%= f.submit "Accept" %>
<% end %>
<%= form_for #thing do |f| %>
<%= hidden_field_tag 'thing[is_accepted]', '0' %>
<%= f.submit "Reject" %>
<% end %>
This feels weird to me, but I can't seem to find anything that says this is the wrong way to do it.
I could, I assume, dry things up by using a partial and/or a helper method, but I wanted to make sure I'm on the right track and not doing something totally wrongly.
You can give your submit tag a name.. ie
<%= form_for #thing do |f| %>
<%= hidden_field_tag 'thing[is_accepted]' %>
<%= f.submit "Accept", :name => 'accept' %>
<%= f.submit "Reject", :name => 'reject' %>
<% end %>
Then you can detect the name in params[] and skip the '1'/'0' value.
I think you're going about it the right way. One way to clean up your forms is by using the model form helpers all the way through, so you'd end up with something like
<%= form_for #thing do |f| %>
<%= f.hidden_field :accepted, :value => true %>
<%= f.submit "Accept" %>
<% end %>
<%= form_for #thing do |f| %>
<%= f.hidden_field :accepted, :value => false %>
<%= f.submit "Reject" %>
<% end %>
But other than that, it looks like the right way to go about it. I would suggest against creating new methods to do this, because you're not doing anything outside of normal web requests (updating a model in this instance).
Using the submit tag as the switch and detecting it in params[] is also a good way, but I usually prefer to keep my controllers as vanilla as possible. In the end, both of these ways would end up with the same amount of 'stuff' in the UI, so whichever style you'd rather use should be fine.
Depending on how you want your UI to work you might consider link_to_remote (part of the prototype helper) - you can specify an action, params etc, and have it return some JS that gets run.
If you're using map.resources in your routes.rb you should be able to do something like this:
map.resources :things, :member => {:accept => :get, :reject => :get}
Then in your controller:
def accept
#thing = Thing.find(params[:id])
#thing.is_accepted = true
#thing.save
end
def reject
#thing = Thing.find(params[:id])
#thing.is_accepted = false
#thing.save
end
And finally in your view:
<%= link_to 'Accept', accept_thing_url(#thing) %>
<%= link_to 'Reject', reject_thing_url(#thing) %>
Or if you are using Ajax:
<%= link_to_remote 'Accept', :url => accept_thing_url(#thing) %>
<%= link_to_remote 'Reject', :url => reject_thing_url(#thing) %>