Rails cache saved files with wrong extension - ruby-on-rails

I have mime type defined
Mime::Type.register "text/html", :demo
and controller which looks like this:
caches_page :show
def show
.....
render_location
end
def render_location
...
respond_to do |format|
format.html {
expires_in 3.days, :public=>true
}
format.demo {
headers['Content-type'] = 'text/html'
render 'fields.html.erb', layout:nil
}
format.json do
out = {
:promo_text => 'text',
:currencies => 'eee'
}
render json: out
end
end
end
Route is set lite this:
get '/prefix/*place', to: 'locations#show', as: 'location', defaults: {format:'html'}
For some reason file in cache folder is saved with .demo extension even when I request for "prefix/some-place"
I can't understand why this happens.

I found that custom extension must be defined with register_alias if it shares Content-type with another presentation.

Related

Rendering Two JSON Items In Rails

This seems like a duplicate question but the answers on the others posts don't seem to work for my issue here.
I'm needing to render two JSON items here within my index method in my controller:
def index
#user = User.all
#libraries = Library.all.order(:created_at)
user_cards = current_user.libraries
render :json => #libraries, :include => :user
render :json => user_cards
end
I attempted to do it this way (failed with a 500 error):
render :json => #libraries, user_cards, :include => :user
And I also attempted to do it this way (also failed with a 500 error): render :json => #libraries :include => [:user, :user_cards]
UPDATE
This is the most recent attempt as rendering the json properly:
def index
#user = User.all
#libraries = Library.all.order(:created_at)
user_cards = current_user.libraries
render json: {
user_cards: user_cards,
libraries: #libraries.as_json(include: [:user])
}
end
The issue with this is that I am now getting an error on libraries throughout my application as it stands. If I simply just render json like I originally had it (render :json => #libraries, :include => :user), I do not get this error. So, I'm assuming the way I have it is still not correct. The exact error on libraries is being called within one of my React components where I use filter:
Error: Uncaught TypeError: this.props.librarys.filter is not a function
Error Location:
let filteredCards = this.props.librarys.filter(
(library) => {
return library.title.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1 || library.desc.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1
}
)
Controller can only return one response, you can achieve this with combining this two returns into one:
respond_to do |format|
format.json { render json: { user_cards: user_cards,
libraries: #libraries } }
end

Rendering template with json params

I have new and create actions like this:
def new
#foo = Foo.new
end
def create
#foo = Foo.new(foo_params)
respond_to do |format|
if #foo.save
format.html { redirect_to root_path }
else
format.html { render :new } //**this line I want to send params**
end
end
end
I have a jbuilder file to new action like this:
new.json.jbuilder
json.foo do
json.a "Some important info"
json.b "Some important info"
end
And rails can't read this file after create's validation fails. How to render a view template (like render :new) and send some json data in this view?
I have a js calling like this:
var json_url = window.location.href + ".json";
var foo;
$.ajax({
url: json_url,
dataType: 'json',
async: false,
success: function(data) {
foo = data.foo;
}
});
If you want Rails to render a file, you'll need to remove the call to redirect_to as it will effectively prevent any rendering.
Furthermore, if you don't want the controller to respond to different formats, it's better to skip the call to respond_to, too.
If you just call render action: :new, the view template will have access to all controller instance variables (like #foo):
json.foo do
json.a #foo.a
json.b #foo.b
end

ActionController::UnknownFormat (format.csv)

I know this question has been asked, but for different formats. My concern is with format.csv.
My Try
Route
match '/something.csv' => 'admin#something', via: :get
Controller
def something
respond_to do |format|
format.csv { render text: ["a", "b"].to_csv } #Just a try
#format.csv { render csv: ["a", "b"].to_csv }
end
end
It throws ActionController::UnknownFormat, when I hit http://localhost:3000/admin/something.csv
EDIT
I was following RailsCast, but could find no suggestions to alter routes like Eg:- defaults: { format: :csv } (as suggested in Kajal Ojha's answer)
I was facing a same error today and it was resolved by providing a default format in route.
In your case it is
match '/something.csv' => 'admin#something', via: :get, defaults: { format: :csv }

Rails Controller Modify JSON Response

I have this method in my controller:
# GET /bios/1
# GET /bios/1.json
def show
if member_session?
#member = MemberPresenter.new(#bio.member)
# I need something here to add a flag to the json response to signal this is a member session.
else
#member = MemberPresenter.new(#bio.member)
end
end
I need to modify the json response to return something like:
{ member: #member, member_session: true }
Thanks in advance!
You can use json param for render functions:
render json: { member: #member, member_session: true }
But it's not the best way to render JSON in rails. I'd recommend you try to use https://github.com/rails-api/active_model_serializers
I'm not sure if you specifically want to return json all the time but here's an alternative to rendering other formats as well:
respond_to do |format|
format.html
format.json { render json: { member: #member, flag: #member.status } }
end
For small and simple objects, doing this is fine, but if you had to drag the associations along, you have the choice of using a serializer, or you could override the to_json method to something like this.
# member.rb
def as_json(options = {})
options = options.merge(
except: [
:updated_at,
:created_at,
],
include: { # Getting associations here
address: {
only: [:street, :zip_code],
include: {
neighbors: { only: :name }
}
}
}
)
super.as_json(options)
end
And finally within the controller, render json: #member.to_json and it will pull all the associations you want with it. This is the lazy man's way of serializing aka what I do :)

Getting RAILS to return a dateTime in a specific format?

I have this controller:
class SchedulesController "post", :except => :index
def index
#Schedules.create(:id => -1, :deviceId => "2002", :subject => "Test 2", :scheduleTime => Time.new, :repeatEveryYear => "FALSE")
##schedules = Schedules.all
respond_to do |format|
format.html # list.html.erb
format.json { render :json => #schedules.to_json }
end
end
def create
#schedule = Schedules.new.from_json(params[:schedule])
#schedule.save
render :json => "success"
end
end
The Schedule has a dateTime field, how can I get the controller to return this time formatted as "yyyy-MM-dd HH:mm:zzzz" (zzzz = Specific GMT timezone)?
Thank you
Søren
You can specify the date and time formats in the initializers. For instance, create the file config/initializers/time.rb and put the following code:
Time::DATE_FORMATS[:schedule] = "%Y-%m-%d %H:%M:%z"
Then in your Schedule.rb:
def formatted_schedule_time
scheduleTime.to_s(:schedule)
end
And every time you call the to_json method on a Schedule object, you need to do:
#schedule.to_json(:methods => [:formatted_schedule_time])

Resources