array public usable en all model, controler and views.. its posible? - ruby-on-rails

I need to fill an array of a search result that their information can be accessed from any model, controller or view. is it possible?
module AdsHelper
attr_reader :table
def initialize
#table = []
end
def add_ads_table(ads)
ads.each do |ad|
#table << ad
end
end
end
#table is the "public" array
class AdsController < ApplicationController
attr_reader :tabla
include AdsHelper
def index
order = sortable_column_order
if params[:search]
#ads = Ad.search(params[:search], params[:page],params[:sort])
add_ads_table(#ads)
else
#ads = Ad.paginate(:per_page => 4, :page => params[:page], :order => order)
add_ads_table(#ads)
end
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #ads }
end
end
end
after completing the array I want to show the information in a view of the same model Ad

Sounds like you're looking for a global variable to me. Just start your variable declaration with an $ instead of #, like this:
def initialize
$table = []
end
Use with care! Globals litering code can end up making a pretty impressive mess of things, not to mention end up with weird scenarios about them. Just a warning.

Related

Rails 5 - Render 2 different post orders on different URLs

I'm sure this is simple but I'm super new to Rails and just can't find the answer from googling.
I have a posts model by default that will be sorted by a custom algorithm (currently sorted by asc). I also want to create another view where it's sorted by newest under mydomain.com/recent
I don't want this done via ajax or anything. I just want the ability to show different views on separate url paths.
posts_controller.erb
def index
#posts = Post.order('created_at ASC').paginate(:page => params[:page], :per_page => 15)
respond_to do |format|
format.html
format.js
end
end
index.html.erb
<%= render #links %>
You could just use scopes in the model and parameters in the controller.
For example if your model had a scope like:
class Post
# Move current controller custom order to scope
scope :my_custom_order, -> { order(created_at: :asc }
scope :recent_order, -> { order(created_at: :desc) }
end
And if you made the /recent part of your URL an optional parameter in your routes.rb file like:
scope '(:order)' do
# Do all your routes to route to PostsController in here
end
Then in your controller you could use that to determine your order for posts, and default back to your custom order for it:
def index
#posts = Post.send(order).paginate(page: params[:page], per_page: 15)
respond_to do |format|
format.html
format.js
end
end
private
def order
:"#{params[:order] || 'my_custom'}_order"
end
Something along those lines with some tweaks to make it work exactly for your project should get you started on what you want to achieve.

How to use the same method in 2 controllers?

I have a Rails 2 app with an API. I versioned and optimised the controllers but there are duplicate methods. The goal is to have the common information in only one place. So I explored the following options:
redirect from routes the non-API controller, but each controller needs it's specific hooks
module inclusion. This is my favorite but there are like quite a lot of errors thrown out and very limited time to fix things up.
eval. Put all the code in one file and eval it in both places. Done this, it works but I am not pleased by this workaround.
What would be the best to go about this?
Might be some typos lurking in here but:
class GenericController < ApplicationController
def index
#objects = params[:controller].singularize.camelcase.constantize.all()
end
def show
#object = params[:controller].singularize.camelcase.constantize.find(params[:id])
end
def new
#object = params[:controller].singularize.camelcase.constantize.new
end
def edit
#object = params[:controller].singularize.camelcase.constantize.find(params[:id])
end
def create
model = params[:controller].singularize.downcase
#object = params[:controller].singularize.camelcase.constantize.new(params[model])
if #object.save
redirect_to '/'+params[:controller]
else
render :action => 'new'
end
end
def update
model = params[:controller].singularize.downcase
#object = params[:controller].singularize.camelcase.constantize.find(params[:id])
if #object.update_attributes(params[model])
redirect_to :controller => params[:controller], :action => 'index'
else
render :action => 'edit'
end
end
def destroy
if #object = params[:controller].singularize.camelcase.constantize.find(params[:id])
#object.destroy
end
redirect_to :controller => params[:controller], :action => 'index'
end
end
Specific controllers can override those implementations as needed, but:
class ProjectsController < GenericController
# done!
end
class ScenariosController < GenericController
# done!
end

Ruby on Rails: Dynamic function name, based on database

How can I create a dynamic function name in rails using the data in the database? I don't know if this is even possible.
here is a sample of my goal
class PageController < ApplicationController
def (PageModel.find(1)) #def stay
#codes here #codes here
end #end
end
I know the syntax is wrong. please help, thanks
Update
this function will only be called via routes, and in my routes I have this line
match "/:action", :controller => "page", :via => "get"
the function will look like this if it is manually generated
def stay
#some query
render 'stay_page', :layout => 'stay_page_layout'
end
def pleasure
#some query
render 'pleasure _page', :layout => 'pleasure _page_layout'
end
In routes.rb:
# Either this...
get "pages/:page", to: "pages#page"
# Or this, but make sure this is the last route in the file
get "/:page", to: "pages#page"
Your controller:
class PageController < ApplicationController
def page
#page = PageModel.find(params[:page])
end
end
If you just need to render different templates depending on the page, you can do this:
def page
#page = PageModel.find(params[:page])
render #page.name
end
If you need custom logic you could do something like this:
VALID_PAGES = ["contact_us"]
def page
#page = PageModel.find(params[:page])
execute(#page.name)
end
def execute(name)
if VALID_PAGES.include?(name)
send(name)
end
end
def contact_us
# do stuff
end
Assuming your PageModel have page_id and page_name, your url get page_id as an parameter, and will render with page_name.
code for controller:
class PageController < ApplicationController
def dynamic_action
page_name = PageModel.find(params[:page_id]).page_name
render "#{page_name}_page", :layout => "#{page_name}_page_layout"
end
end
route:
match '/:page_id' => 'page#dynamic_action'

No field configured for Model with name 'image_filename'

I have a Model with 2 atrributes:
:image_filename
:yt_video_id
I have this code in my controller:
def index
#search = Model.solr_search do |s|
s.fulltext params[:search]
s.paginate :page => params[:page], :per_page => 2
s.with(:image_filename || :yt_video_id)
end
#model = #search.results
respond_to do |format|
format.html # index.html.erb
end
end
in my model.rb Model I have this in searchable:
searchable do
string :image_filename, :yt_video_id
end
I want filter :image_filename OR :yt_video_id any are not "nil". I mean, both attributes must have a mandatory value.
but I get the error:
Sunspot::UnrecognizedFieldError in ModelsController#index
No field configured for Model with name 'image_filename'
The problem was fixed with the following steps:
(This solution works fine for me. I hope this solution can help you too.)
In model.rb you can not write this syntax:
searchable do
string :image_filename, :yt_video_id
end
You must write this syntax:
searchable do
string :image_filename
string :yt_video_id
end
In your models_controller.rb in index action:
def index
#search = Model.solr_search do |s|
s.fulltext params[:search]
s.paginate :page => params[:page], :per_page => 2
s.any_of do
without(:image_filename, nil)
without(:yt_video_id, nil)
end
end
#model = #search.results
respond_to do |format|
format.html # index.html.erb
end
end
I have used the any_of method.
To combine scopes using OR semantics, use the any_of method to group restrictions into a disjunction:
Sunspot.search(Post) do
any_of do
with(:expired_at).greater_than(Time.now)
with(:expired_at, nil)
end
end
You can see in https://github.com/sunspot/sunspot/wiki/Scoping-by-attribute-fields

Rails: include related object in JSON output

I have a note class that belongs to a user (ie a user can create many notes).
clip from my notes controller
class NotesController < ApplicationController
before_filter :authenticate_user!
respond_to :html, :xml, :json
# GET /notes
# GET /notes.xml
def index
#notes = Note.includes(:user).order("created_at DESC")
respond_with #notes
end
When I ask for the index in json results for example /notes.json, it returns the notes but only returns user_id for the user object. I would like it to also include user.username (and would be curious how to have the whole user object embedded).
Bonus question: I could not find a way to make the column show as author_id and have it relate back to user. If this is easy to do, how do you do it?
I'm not sure the new respond_to/respond_with style is flexible enough to do this. It very well may be, but as far as I understand, it's meant to simplify only the simplest cases.
You can achieve what you are trying to do with the old-style respond_to with a block, however, by passing parameters to to_json. Try something like this:
class NotesController < ApplicationController
def index
#notes = Note.order("created_at desc")
respond_to do |format|
format.json do
render :json => #notes.to_json(:include => { :user => { :only => :username } })
end
end
end
end
You can also use Jbuilder(https://github.com/rails/jbuilder) to response with data very flexible.
#notes = Note.includes(:user).order("created_at DESC")
and in your index.json.jbuilder file, you can
json.extract! #note
json.username #note.user.username
Would it be possible to do it the other way around?
def index
#user = User.includes(:notes).order("created_at DESC")
respond_with #user
end
It would be expensive to include user objects each time the #notes is iterated.

Resources